From 41e390d52c8015e0ff3f41d7ff0f6c348732fb82 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 25 Jun 2020 19:46:49 +0200 Subject: [PATCH 1/3] Validate data segment offset initializer expressions --- lib/fizzy/parser.cpp | 3 +++ test/unittests/instantiate_test.cpp | 16 ++++++++-------- test/unittests/parser_test.cpp | 16 +++++++++++----- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/fizzy/parser.cpp b/lib/fizzy/parser.cpp index 86e8f9667..465773fea 100644 --- a/lib/fizzy/parser.cpp +++ b/lib/fizzy/parser.cpp @@ -537,6 +537,9 @@ Module parse(bytes_view input) if (!module.datasec.empty() && !module.has_memory()) throw validation_error{"data section encountered without a memory section"}; + for (const auto& data : module.datasec) + validate_constant_expression(data.offset, module); + if (module.imported_table_types.size() > 1) throw validation_error{"too many imported tables (at most one is allowed)"}; diff --git a/test/unittests/instantiate_test.cpp b/test/unittests/instantiate_test.cpp index f2e3dd4b3..5a132cf53 100644 --- a/test/unittests/instantiate_test.cpp +++ b/test/unittests/instantiate_test.cpp @@ -679,15 +679,15 @@ TEST(instantiate, data_section_offset_from_imported_global) TEST(instantiate, data_section_offset_from_mutable_global) { - Module module; - module.memorysec.emplace_back(Memory{{1, 1}}); - module.globalsec.emplace_back( - Global{{ValType::i32, true}, {ConstantExpression::Kind::Constant, {42}}}); - // Memory contents: 0, 0xaa, 0xff, 0, ... - module.datasec.emplace_back(Data{{ConstantExpression::Kind::GlobalGet, {0}}, {0xaa, 0xff}}); + /* wat2wasm --no-check + (global (mut i32) (i32.const 42)) + (memory 1 1) + (data (global.get 0) "\aa\ff") + */ + const auto bin = from_hex("0061736d010000000504010101010606017f01412a0b0b08010023000b02aaff"); - EXPECT_THROW_MESSAGE(instantiate(module), instantiate_error, - "constant expression can use global_get only for const globals"); + EXPECT_THROW_MESSAGE(parse(bin), validation_error, + "constant expression can use global.get only for const globals"); } TEST(instantiate, data_section_offset_too_large) diff --git a/test/unittests/parser_test.cpp b/test/unittests/parser_test.cpp index 26b2cde83..89d00d616 100644 --- a/test/unittests/parser_test.cpp +++ b/test/unittests/parser_test.cpp @@ -1263,12 +1263,18 @@ TEST(parser, data_section_empty) TEST(parser, data_section) { - const auto section_contents = - make_vec({"0041010b02aaff"_bytes, "0041020b025555"_bytes, "0023000b022424"_bytes}); - const auto bin = bytes{wasm_prefix} + make_section(5, make_vec({"0000"_bytes})) + - make_section(11, section_contents); - + /* wat2wasm + (global (import "m" "g") i32) + (memory 0) + (data (i32.const 1) "\aa\ff") + (data (i32.const 2) "\55\55") + (data (global.get 0) "\24\24") + */ + const auto bin = from_hex( + "0061736d01000000020801016d0167037f0005030100000b16030041010b02aaff0041020b0255550023000b02" + "2424"); const auto module = parse(bin); + ASSERT_EQ(module.datasec.size(), 3); EXPECT_EQ(module.datasec[0].offset.kind, ConstantExpression::Kind::Constant); EXPECT_EQ(module.datasec[0].offset.value.constant, 1); From 154ad042b6d4f2c4ca0ed853a91fa23fa32f2651 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 25 Jun 2020 19:47:18 +0200 Subject: [PATCH 2/3] test: move data section offset validation tests to validation_test.cpp --- test/unittests/instantiate_test.cpp | 13 ------------- test/unittests/validation_test.cpp | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/unittests/instantiate_test.cpp b/test/unittests/instantiate_test.cpp index 5a132cf53..1d6c3614c 100644 --- a/test/unittests/instantiate_test.cpp +++ b/test/unittests/instantiate_test.cpp @@ -677,19 +677,6 @@ TEST(instantiate, data_section_offset_from_imported_global) EXPECT_EQ(instance->memory->substr(42, 2), "aaff"_bytes); } -TEST(instantiate, data_section_offset_from_mutable_global) -{ - /* wat2wasm --no-check - (global (mut i32) (i32.const 42)) - (memory 1 1) - (data (global.get 0) "\aa\ff") - */ - const auto bin = from_hex("0061736d010000000504010101010606017f01412a0b0b08010023000b02aaff"); - - EXPECT_THROW_MESSAGE(parse(bin), validation_error, - "constant expression can use global.get only for const globals"); -} - TEST(instantiate, data_section_offset_too_large) { Module module; diff --git a/test/unittests/validation_test.cpp b/test/unittests/validation_test.cpp index ebd6635ec..a5191b662 100644 --- a/test/unittests/validation_test.cpp +++ b/test/unittests/validation_test.cpp @@ -118,6 +118,19 @@ TEST(validation, table_multi_min_limit) parse(bin), validation_error, "too many table sections (at most one is allowed)"); } +TEST(validation, data_section_offset_from_mutable_global) +{ + /* wat2wasm --no-check + (global (mut i32) (i32.const 42)) + (memory 1 1) + (data (global.get 0) "\aa\ff") + */ + const auto bin = from_hex("0061736d010000000504010101010606017f01412a0b0b08010023000b02aaff"); + + EXPECT_THROW_MESSAGE(parse(bin), validation_error, + "constant expression can use global.get only for const globals"); +} + TEST(validation, i32_store_no_memory) { /* wat2wasm --no-check From 661d6592c3af5f93f0a8bf60f8ead8c05d594ae6 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Thu, 25 Jun 2020 19:47:31 +0200 Subject: [PATCH 3/3] test: invalid global index in data section offset expression --- test/unittests/validation_test.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/unittests/validation_test.cpp b/test/unittests/validation_test.cpp index a5191b662..c3a27fa89 100644 --- a/test/unittests/validation_test.cpp +++ b/test/unittests/validation_test.cpp @@ -118,16 +118,25 @@ TEST(validation, table_multi_min_limit) parse(bin), validation_error, "too many table sections (at most one is allowed)"); } -TEST(validation, data_section_offset_from_mutable_global) +TEST(validation, data_section_invalid_offset_expression) { + /* wat2wasm --no-check + (memory 1 1) + (data (global.get 0) "\aa\ff") + */ + const auto bin1 = from_hex("0061736d010000000504010101010b08010023000b02aaff"); + + EXPECT_THROW_MESSAGE( + parse(bin1), validation_error, "invalid global index in constant expression"); + /* wat2wasm --no-check (global (mut i32) (i32.const 42)) (memory 1 1) (data (global.get 0) "\aa\ff") */ - const auto bin = from_hex("0061736d010000000504010101010606017f01412a0b0b08010023000b02aaff"); + const auto bin2 = from_hex("0061736d010000000504010101010606017f01412a0b0b08010023000b02aaff"); - EXPECT_THROW_MESSAGE(parse(bin), validation_error, + EXPECT_THROW_MESSAGE(parse(bin2), validation_error, "constant expression can use global.get only for const globals"); }