[wasm] Validate memory.init and memory.drop
The memory.init and memory.drop instructions have a data segment index that can only be validated by knowing the number of data segments. This information is provided by the new DataCount section. Bug: v8:7747 Change-Id: Ie04d57584fe028637f6e931ab53d00abc5b998a4 Reviewed-on: https://chromium-review.googlesource.com/c/1355624 Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Commit-Queue: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#58031}
This commit is contained in:
parent
a31338aa08
commit
216fb64816
@ -1077,12 +1077,21 @@ class WasmDecoder : public Decoder {
|
||||
|
||||
inline bool Validate(MemoryInitImmediate<validate>& imm) {
|
||||
if (!Validate(imm.memory)) return false;
|
||||
// TODO(binji): validate imm.data_segment_index
|
||||
if (!VALIDATE(module_ != nullptr &&
|
||||
imm.data_segment_index <
|
||||
module_->num_declared_data_segments)) {
|
||||
errorf(pc_ + 2, "invalid data segment index: %u", imm.data_segment_index);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Validate(MemoryDropImmediate<validate>& imm) {
|
||||
// TODO(binji): validate imm.data_segment_index
|
||||
if (!VALIDATE(module_ != nullptr &&
|
||||
imm.index < module_->num_declared_data_segments)) {
|
||||
errorf(pc_ + 2, "invalid data segment index: %u", imm.index);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -870,9 +870,9 @@ class ModuleDecoderImpl : public Decoder {
|
||||
|
||||
bool CheckDataSegmentsCount(uint32_t data_segments_count) {
|
||||
if (has_seen_unordered_section(kDataCountSectionCode) &&
|
||||
data_segments_count != num_declared_data_segments_) {
|
||||
data_segments_count != module_->num_declared_data_segments) {
|
||||
errorf(pc(), "data segments count %u mismatch (%u expected)",
|
||||
data_segments_count, num_declared_data_segments_);
|
||||
data_segments_count, module_->num_declared_data_segments);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -968,7 +968,7 @@ class ModuleDecoderImpl : public Decoder {
|
||||
}
|
||||
|
||||
void DecodeDataCountSection() {
|
||||
num_declared_data_segments_ =
|
||||
module_->num_declared_data_segments =
|
||||
consume_count("data segments count", kV8MaxWasmDataSegments);
|
||||
}
|
||||
|
||||
@ -1120,8 +1120,6 @@ class ModuleDecoderImpl : public Decoder {
|
||||
"not enough bits");
|
||||
VoidResult intermediate_result_;
|
||||
ModuleOrigin origin_;
|
||||
// The number of data segments as specified by the DataCount section.
|
||||
uint32_t num_declared_data_segments_ = 0;
|
||||
|
||||
bool has_seen_unordered_section(SectionCode section_code) {
|
||||
return seen_unordered_sections_ & (1 << section_code);
|
||||
|
@ -170,6 +170,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
|
||||
uint32_t num_imported_functions = 0;
|
||||
uint32_t num_declared_functions = 0; // excluding imported
|
||||
uint32_t num_exported_functions = 0;
|
||||
uint32_t num_declared_data_segments = 0; // From the DataCount section.
|
||||
WireBytesRef name = {0, 0};
|
||||
std::vector<FunctionSig*> signatures; // by signature index
|
||||
std::vector<uint32_t> signature_ids; // by signature index
|
||||
|
@ -268,6 +268,13 @@ class TestModuleBuilder {
|
||||
return static_cast<byte>(mod.table_inits.size() - 1);
|
||||
}
|
||||
|
||||
// Set the number of data segments as declared by the DataCount section.
|
||||
void SetDataSegmentCount(uint32_t data_segment_count) {
|
||||
// The Data section occurs after the Code section, so we don't need to
|
||||
// update mod.data_segments, as it is always empty.
|
||||
mod.num_declared_data_segments = data_segment_count;
|
||||
}
|
||||
|
||||
WasmModule* module() { return &mod; }
|
||||
|
||||
private:
|
||||
@ -2738,17 +2745,19 @@ TEST_F(FunctionBodyDecoderTest, Regression709741) {
|
||||
TEST_F(FunctionBodyDecoderTest, MemoryInit) {
|
||||
TestModuleBuilder builder;
|
||||
builder.InitializeMemory();
|
||||
builder.SetDataSegmentCount(1);
|
||||
module = builder.module();
|
||||
|
||||
EXPECT_FAILURE(v_v, WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
||||
WASM_FEATURE_SCOPE(bulk_memory);
|
||||
EXPECT_VERIFIES(v_v, WASM_MEMORY_INIT(0, WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
||||
// TODO(binji): validate segment index.
|
||||
EXPECT_FAILURE(v_v, WASM_TABLE_INIT(1, WASM_ZERO, WASM_ZERO, WASM_ZERO));
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MemoryInitInvalid) {
|
||||
TestModuleBuilder builder;
|
||||
builder.InitializeMemory();
|
||||
builder.SetDataSegmentCount(1);
|
||||
module = builder.module();
|
||||
|
||||
WASM_FEATURE_SCOPE(bulk_memory);
|
||||
@ -2760,10 +2769,15 @@ TEST_F(FunctionBodyDecoderTest, MemoryInitInvalid) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MemoryDrop) {
|
||||
TestModuleBuilder builder;
|
||||
builder.InitializeMemory();
|
||||
builder.SetDataSegmentCount(1);
|
||||
module = builder.module();
|
||||
|
||||
EXPECT_FAILURE(v_v, WASM_MEMORY_DROP(0));
|
||||
WASM_FEATURE_SCOPE(bulk_memory);
|
||||
EXPECT_VERIFIES(v_v, WASM_MEMORY_DROP(0));
|
||||
// TODO(binji): validate segment index.
|
||||
EXPECT_FAILURE(v_v, WASM_MEMORY_DROP(1));
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, MemoryCopy) {
|
||||
|
Loading…
Reference in New Issue
Block a user