From 8167820bff412590aa52203b4b972a4768f4da76 Mon Sep 17 00:00:00 2001 From: rossberg-chromium Date: Wed, 25 Jan 2017 13:18:48 +0100 Subject: [PATCH] Detect bounds wrap-around --- interpreter/Makefile | 7 +++++-- interpreter/spec/eval.ml | 6 ++++-- test/core/call_indirect.wast | 34 +++++++++++++++++++++++++++++++++- test/core/memory.wast | 17 ++++++++++++++++- 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/interpreter/Makefile b/interpreter/Makefile index 4ad789056d..aae1882f87 100644 --- a/interpreter/Makefile +++ b/interpreter/Makefile @@ -89,10 +89,13 @@ $(ZIP): $(WINMAKE) git archive --format=zip --prefix=$(NAME)/ -o $@ HEAD test: $(NAME) - ../test/core/run.py --wasm `pwd`/wasm $(if $(JS),--js '$(JS)',) + ../test/core/run.py --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) test/%: $(NAME) - ../test/core/run.py --wasm `pwd`/wasm $(if $(JS),--js '$(JS)',) $(@:test/%=../test/core/%.wast) + ../test/core/run.py --wasm `pwd`/$(NAME) $(if $(JS),--js '$(JS)',) $(@:test/%=../test/core/%.wast) + +run/%: $(NAME) + ./$(NAME) $(@:run/%=../test/core/%.wast) clean: $(OCB) -clean diff --git a/interpreter/spec/eval.ml b/interpreter/spec/eval.ml index c0f67b12ab..d7bf9f8946 100644 --- a/interpreter/spec/eval.ml +++ b/interpreter/spec/eval.ml @@ -364,8 +364,9 @@ let init_table (inst : instance) (seg : table_segment) = let {index; offset = const; init} = seg.it in let tab = table inst index in let offset = i32 (eval_const inst const) const.at in + let end_ = Int32.(add offset (of_int (List.length init))) in let bound = Table.size tab in - if I32.lt_u bound Int32.(add offset (of_int (List.length init))) then + if I32.lt_u bound end_ || I32.lt_u end_ offset then Link.error seg.at "elements segment does not fit table"; fun () -> Table.blit tab offset (List.map (fun x -> Func (func inst x)) init) @@ -374,8 +375,9 @@ let init_memory (inst : instance) (seg : memory_segment) = let mem = memory inst index in let offset' = i32 (eval_const inst const) const.at in let offset = I64_convert.extend_u_i32 offset' in + let end_ = Int64.(add offset (of_int (String.length init))) in let bound = Memory.bound mem in - if I64.lt_u bound Int64.(add offset (of_int (String.length init))) then + if I64.lt_u bound end_ || I64.lt_u end_ offset then Link.error seg.at "data segment does not fit memory"; fun () -> Memory.blit mem offset init diff --git a/test/core/call_indirect.wast b/test/core/call_indirect.wast index 702381eda5..532f613c99 100644 --- a/test/core/call_indirect.wast +++ b/test/core/call_indirect.wast @@ -361,8 +361,40 @@ "unknown type" ) -;; invalid table + +;; Unbound function in table + (assert_invalid (module (table anyfunc (elem 0 0))) "unknown function 0" ) + + +;; Invalid bounds for elements + +(assert_unlinkable + (module + (table 10 anyfunc) + (elem (i32.const 10) $f) + (func $f) + ) + "elements segment does not fit" +) + +(assert_unlinkable + (module + (table 10 anyfunc) + (elem (i32.const -1) $f) + (func $f) + ) + "elements segment does not fit" +) + +(assert_unlinkable + (module + (table 10 anyfunc) + (elem (i32.const -10) $f) + (func $f) + ) + "elements segment does not fit" +) diff --git a/test/core/memory.wast b/test/core/memory.wast index a3b056843e..c477ea4338 100644 --- a/test/core/memory.wast +++ b/test/core/memory.wast @@ -81,6 +81,14 @@ (module (memory 0 1) (data (i32.const 0) "a")) "data segment does not fit" ) +(assert_unlinkable + (module (memory 1 2) (data (i32.const -1) "a")) + "data segment does not fit" +) +(assert_unlinkable + (module (memory 1 2) (data (i32.const -1000) "a")) + "data segment does not fit" +) (assert_unlinkable (module (memory 1 2) (data (i32.const 0) "a") (data (i32.const 98304) "b")) "data segment does not fit" @@ -93,13 +101,20 @@ (module (memory 1) (data (i32.const 0x12000) "")) "data segment does not fit" ) +(assert_unlinkable + (module (memory 1 2) (data (i32.const -1) "")) + "data segment does not fit" +) ;; This seems to cause a time-out on Travis. (;assert_unlinkable (module (memory 0x10000) (data (i32.const 0xffffffff) "ab")) "" ;; either out of memory or segment does not fit ;) (assert_unlinkable - (module (global (import "spectest" "global") i32) (memory 0) (data (get_global 0) "a")) + (module + (global (import "spectest" "global") i32) + (memory 0) (data (get_global 0) "a") + ) "data segment does not fit" )