Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: src/wasm/module-decoder.cc

Issue 1608743006: [wasm] Verify boundaries of data segments when decoding modules. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/wasm/wasm-js.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/macro-assembler.h" 5 #include "src/macro-assembler.h"
6 #include "src/objects.h" 6 #include "src/objects.h"
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/wasm/decoder.h" 9 #include "src/wasm/decoder.h"
10 #include "src/wasm/module-decoder.h" 10 #include "src/wasm/module-decoder.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 int length; 150 int length;
151 uint32_t data_segments_count = u32v(&length, "data segments count"); 151 uint32_t data_segments_count = u32v(&length, "data segments count");
152 module->data_segments->reserve(SafeReserve(data_segments_count)); 152 module->data_segments->reserve(SafeReserve(data_segments_count));
153 // Decode data segments. 153 // Decode data segments.
154 for (uint32_t i = 0; i < data_segments_count; i++) { 154 for (uint32_t i = 0; i < data_segments_count; i++) {
155 if (failed()) break; 155 if (failed()) break;
156 TRACE("DecodeDataSegment[%d] module+%d\n", i, 156 TRACE("DecodeDataSegment[%d] module+%d\n", i,
157 static_cast<int>(pc_ - start_)); 157 static_cast<int>(pc_ - start_));
158 module->data_segments->push_back({0, 0, 0}); 158 module->data_segments->push_back({0, 0, 0});
159 WasmDataSegment* segment = &module->data_segments->back(); 159 WasmDataSegment* segment = &module->data_segments->back();
160 DecodeDataSegmentInModule(segment); 160 DecodeDataSegmentInModule(module, segment);
161 } 161 }
162 break; 162 break;
163 } 163 }
164 case kDeclFunctionTable: { 164 case kDeclFunctionTable: {
165 // An indirect function table requires functions first. 165 // An indirect function table requires functions first.
166 CheckForPreviousSection(sections, kDeclFunctions, true); 166 CheckForPreviousSection(sections, kDeclFunctions, true);
167 int length; 167 int length;
168 uint32_t function_table_count = u32v(&length, "function table count"); 168 uint32_t function_table_count = u32v(&length, "function table count");
169 module->function_table->reserve(SafeReserve(function_table_count)); 169 module->function_table->reserve(SafeReserve(function_table_count));
170 // Decode function table. 170 // Decode function table.
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 "expected %d bytes for function body, fell off end", size); 338 "expected %d bytes for function body, fell off end", size);
339 } 339 }
340 function->code_start_offset = static_cast<uint32_t>(pc_ - start_); 340 function->code_start_offset = static_cast<uint32_t>(pc_ - start_);
341 function->code_end_offset = function->code_start_offset + size; 341 function->code_end_offset = function->code_start_offset + size;
342 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_), 342 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_),
343 "function body", size); 343 "function body", size);
344 pc_ += size; 344 pc_ += size;
345 } 345 }
346 } 346 }
347 347
348 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) {
349 if (offset > limit) return false;
350 if ((offset + size) < offset) return false; // overflow
351 return (offset + size) <= limit;
352 }
353
348 // Decodes a single data segment entry inside a module starting at {pc_}. 354 // Decodes a single data segment entry inside a module starting at {pc_}.
349 void DecodeDataSegmentInModule(WasmDataSegment* segment) { 355 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) {
350 segment->dest_addr = 356 segment->dest_addr = u32("destination");
351 u32("destination"); // TODO(titzer): check it's within the memory size.
352 segment->source_offset = offset("source offset"); 357 segment->source_offset = offset("source offset");
353 segment->source_size = 358 segment->source_size = u32("source size");
354 u32("source size"); // TODO(titzer): check the size is reasonable.
355 segment->init = u8("init"); 359 segment->init = u8("init");
360
361 // Validate the data is in the module.
362 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_);
363 if (!IsWithinLimit(module_limit, segment->source_offset,
364 segment->source_size)) {
365 error(pc_ - sizeof(uint32_t), "segment out of bounds of module");
366 }
367
368 // Validate that the segment will fit into the (minimum) memory.
369 uint32_t memory_limit =
370 1 << (module ? module->min_mem_size_log2 : WasmModule::kMaxMemSize);
371 if (!IsWithinLimit(memory_limit, segment->dest_addr,
372 segment->source_size)) {
373 error(pc_ - sizeof(uint32_t), "segment out of bounds of memory");
374 }
356 } 375 }
357 376
358 // Verifies the body (code) of a given function. 377 // Verifies the body (code) of a given function.
359 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, 378 void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv,
360 WasmFunction* function) { 379 WasmFunction* function) {
361 if (FLAG_trace_wasm_decode_time) { 380 if (FLAG_trace_wasm_decode_time) {
362 // TODO(titzer): clean me up a bit. 381 // TODO(titzer): clean me up a bit.
363 OFStream os(stdout); 382 OFStream os(stdout);
364 os << "Verifying WASM function:"; 383 os << "Verifying WASM function:";
365 if (function->name_offset > 0) { 384 if (function->name_offset > 0) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 if (function_start > function_end) return FunctionError("start > end"); 557 if (function_start > function_end) return FunctionError("start > end");
539 if (size > kMaxFunctionSize) 558 if (size > kMaxFunctionSize)
540 return FunctionError("size > maximum function size"); 559 return FunctionError("size > maximum function size");
541 WasmFunction* function = new WasmFunction(); 560 WasmFunction* function = new WasmFunction();
542 ModuleDecoder decoder(zone, function_start, function_end, false); 561 ModuleDecoder decoder(zone, function_start, function_end, false);
543 return decoder.DecodeSingleFunction(module_env, function); 562 return decoder.DecodeSingleFunction(module_env, function);
544 } 563 }
545 } // namespace wasm 564 } // namespace wasm
546 } // namespace internal 565 } // namespace internal
547 } // namespace v8 566 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/wasm-js.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698