Skip to content

Commit ee7bdb5

Browse files
authored
[interpreter/test] Fix boundary conditions on memory/table growth (#2290)
1 parent a550c39 commit ee7bdb5

8 files changed

Lines changed: 74 additions & 5 deletions

File tree

‎interpreter/exec/eval.ml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ let eval_const (inst : moduleinst) (const : const) : value =
11731173
| [v] -> v
11741174
| vs -> Crash.error const.at "wrong number of results on stack"
11751175

1176+
11761177
(* Modules *)
11771178

11781179
let init_type (inst : moduleinst) (type_ : type_) : moduleinst =

‎interpreter/runtime/memory.ml‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,17 @@ let valid_limits {min; max} =
2626

2727
let valid_size at i =
2828
match at with
29-
| I32AT -> I64.le_u i 0xffffL
30-
| I64AT -> true
29+
| I32AT -> I64.le_u i 0x1_0000L
30+
| I64AT -> I64.le_u i 0x1_0000_0000_0000L
3131

3232
let create n =
33+
if n > Int64.(div max_int page_size) then raise OutOfMemory else
34+
let size = Int64.(mul n page_size) in
3335
try
34-
let size = Int64.(mul n page_size) in
3536
let mem = Array1_64.create Int8_unsigned C_layout size in
3637
Array1.fill mem 0;
3738
mem
38-
with Out_of_memory -> raise OutOfMemory
39+
with Out_of_memory | Invalid_argument _ -> raise OutOfMemory
3940

4041
let alloc (MemoryT (at, lim) as ty) =
4142
assert Free.((memorytype ty).types = Set.empty);

‎interpreter/runtime/table.ml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ let valid_size at i =
2424
| I64AT -> true
2525

2626
let create size r =
27+
if size < 0L then raise OutOfMemory else
2728
try Lib.Array64.make size r
2829
with Out_of_memory | Invalid_argument _ -> raise OutOfMemory
2930

‎spectec/src/backend-interpreter/interpreter.ml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ and eval_expr env expr =
370370
(* Optimized getter for list init *)
371371
| IterE (e1, (ListN (e2, None), [])) ->
372372
let v = eval_expr env e1 in
373-
let i = eval_expr env e2 |> al_to_nat in
373+
let i = try eval_expr env e2 |> al_to_nat with Z.Overflow -> raise Exception.OutOfMemory in
374374
if i > 1024 * 64 * 1024 (* 1024 pages *) then
375375
raise Exception.OutOfMemory
376376
else

‎test/core/memory64/memory_grow64.wast‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,18 @@
9393
(assert_return (invoke "check-memory-zero" (i64.const 0x40000) (i64.const 0x4_ffff)) (i32.const 0))
9494
(assert_return (invoke "grow" (i64.const 1)) (i64.const 5))
9595
(assert_return (invoke "check-memory-zero" (i64.const 0x50000) (i64.const 0x5_ffff)) (i32.const 0))
96+
97+
98+
(module
99+
(memory i64 1)
100+
(func (export "grow") (param i64) (result i64) (memory.grow (local.get 0)))
101+
(func (export "size") (result i64) (memory.size))
102+
)
103+
(assert_return (invoke "grow" (i64.const 0x1_0000_0000_0000)) (i64.const -1))
104+
(assert_return (invoke "size") (i64.const 1))
105+
(assert_return (invoke "grow" (i64.const 0xFFFF_FFFF_FFFF))
106+
(either (i64.const -1) (i64.const 1))
107+
)
108+
(assert_return (invoke "size")
109+
(either (i64.const 1) (i64.const 0x1_0000_0000_0000))
110+
)

‎test/core/memory64/table_grow64.wast‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,20 @@
3232
(assert_return (invoke "get-t64" (i64.const 4)) (ref.extern 4))
3333
(assert_trap (invoke "set-t64" (i64.const 5) (ref.extern 2)) "out of bounds table access")
3434
(assert_trap (invoke "get-t64" (i64.const 5)) "out of bounds table access")
35+
36+
37+
(module
38+
(table i64 1 funcref)
39+
(func (export "grow") (param i64) (result i64)
40+
(table.grow (ref.null func) (local.get 0))
41+
)
42+
(func (export "size") (result i64) (table.size))
43+
)
44+
(assert_return (invoke "grow" (i64.const 0xFFFF_FFFF_FFFF_FFFF)) (i64.const -1))
45+
(assert_return (invoke "size") (i64.const 1))
46+
(assert_return (invoke "grow" (i64.const 0xFFFF_FFFF_FFFF_FFFE))
47+
(either (i64.const -1) (i64.const 1))
48+
)
49+
(assert_return (invoke "size")
50+
(either (i64.const 1) (i64.const 0xFFFF_FFFF_FFFF_FFFF))
51+
)

‎test/core/memory_grow.wast‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,3 +424,19 @@
424424
)
425425
"type mismatch"
426426
)
427+
428+
429+
(module
430+
(memory 1)
431+
(func (export "grow") (param i32) (result i32) (memory.grow (local.get 0)))
432+
(func (export "size") (result i32) (memory.size))
433+
)
434+
(assert_return (invoke "grow" (i32.const 0x1_0000)) (i32.const -1))
435+
(assert_return (invoke "size") (i32.const 1))
436+
;; This may be too slow on some implementations
437+
;; (assert_return (invoke "grow" (i32.const 0xFFFF))
438+
;; (either (i32.const -1) (i32.const 1))
439+
;; )
440+
;; (assert_return (invoke "size")
441+
;; (either (i32.const 1) (i32.const 0x1_0000))
442+
;; )

‎test/core/table_grow.wast‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,21 @@
196196
)
197197
"type mismatch"
198198
)
199+
200+
201+
(module
202+
(table 1 funcref)
203+
(func (export "grow") (param i32) (result i32)
204+
(table.grow (ref.null func) (local.get 0))
205+
)
206+
(func (export "size") (result i32) (table.size))
207+
)
208+
(assert_return (invoke "grow" (i32.const 0xFFFF_FFFF)) (i32.const -1))
209+
(assert_return (invoke "size") (i32.const 1))
210+
;; This may be too slow on some implementations
211+
;; (assert_return (invoke "grow" (i32.const 0xFFFF_FFFE))
212+
;; (either (i32.const -1) (i32.const 1))
213+
;; )
214+
;; (assert_return (invoke "size")
215+
;; (either (i32.const 1) (i32.const 0xFFFF_FFFF))
216+
;; )

0 commit comments

Comments
 (0)