Skip to content

Commit

Permalink
Fix function section validation
Browse files Browse the repository at this point in the history
The validation of type indices in function section must be fully
finished before processing any code. This is because there may be a call
in code[i] referencing function[i + n].
  • Loading branch information
chfast committed May 25, 2020
1 parent 7687576 commit e03eaeb
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
10 changes: 7 additions & 3 deletions lib/fizzy/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ Module parse(bytes_view input)
}
}

for (const auto type_idx : module.funcsec)
{
if (type_idx >= module.typesec.size())
throw validation_error{"invalid function type index"};
}

if (module.tablesec.size() > 1)
throw validation_error{"too many table sections (at most one is allowed)"};

Expand Down Expand Up @@ -533,9 +539,7 @@ Module parse(bytes_view input)
module.codesec.reserve(code_binaries.size());
for (size_t i = 0; i < code_binaries.size(); ++i)
{
const auto type_idx = module.funcsec[i];
if (type_idx >= module.typesec.size())
throw validation_error{"invalid function type index"};
assert(module.funcsec[i] < module.typesec.size());
module.codesec.emplace_back(parse_code(code_binaries[i], module));
}

Expand Down
14 changes: 13 additions & 1 deletion test/unittests/parser_expr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,16 @@ TEST(parser_expr, call_1arg_1result)

const auto module = parse(wasm);
ASSERT_EQ(module.codesec.size(), 2);
}
}

TEST(parser_expr, call_nonexisting_typeidx)
{
// This creates a wasm module where code[0] has a call instruction calling function[1] which
// has invalid type_idx 1.
// wat2wasm cannot be used as there is no way to have invalid type_idx in WAT form.
const auto wasm = bytes{wasm_prefix} + make_section(1, make_vec({"600000"_bytes})) +
make_section(3, make_vec({"00"_bytes, "01"_bytes})) +
make_section(10, make_vec({"040010010b"_bytes, "02000b"_bytes}));

EXPECT_THROW_MESSAGE(parse(wasm), validation_error, "invalid function type index");
}
4 changes: 3 additions & 1 deletion test/unittests/parser_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,10 @@ TEST(parser, function_section_end_out_of_bounds)

TEST(parser, function_section_without_code)
{
const auto type_section = make_vec({make_functype({}, {})});
const auto function_section = "0100"_bytes;
const auto bin = bytes{wasm_prefix} + make_section(3, function_section);
const auto bin =
bytes{wasm_prefix} + make_section(1, type_section) + make_section(3, function_section);
EXPECT_THROW_MESSAGE(parse(bin), parser_error,
"malformed binary: number of function and code entries must match");
}
Expand Down

0 comments on commit e03eaeb

Please sign in to comment.