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

Side by Side Diff: test/unittests/wasm/module-decoder-unittest.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 | « src/wasm/wasm-opcodes.cc ('k') | no next file » | 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 "test/unittests/test-utils.h" 5 #include "test/unittests/test-utils.h"
6 6
7 #include "src/wasm/module-decoder.h" 7 #include "src/wasm/module-decoder.h"
8 #include "src/wasm/wasm-opcodes.h" 8 #include "src/wasm/wasm-opcodes.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 27 matching lines...) Expand all
38 38
39 struct LocalTypePair { 39 struct LocalTypePair {
40 uint8_t code; 40 uint8_t code;
41 LocalType type; 41 LocalType type;
42 } kLocalTypes[] = {{kLocalI32, kAstI32}, 42 } kLocalTypes[] = {{kLocalI32, kAstI32},
43 {kLocalI64, kAstI64}, 43 {kLocalI64, kAstI64},
44 {kLocalF32, kAstF32}, 44 {kLocalF32, kAstF32},
45 {kLocalF64, kAstF64}}; 45 {kLocalF64, kAstF64}};
46 46
47 47
48 // TODO(titzer): use these macros everywhere below.
49 #define U32_LE(v) \
50 static_cast<byte>(v), static_cast<byte>((v) >> 8), \
51 static_cast<byte>((v) >> 16), static_cast<byte>((v) >> 24)
52
53
54 #define U16_LE(v) static_cast<byte>(v), static_cast<byte>((v) >> 8)
55
56
48 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { 57 TEST_F(WasmModuleVerifyTest, DecodeEmpty) {
49 static const byte data[1]{kDeclEnd}; 58 static const byte data[1]{kDeclEnd};
50 { 59 {
51 ModuleResult result = DecodeModule(data, data); 60 ModuleResult result = DecodeModule(data, data);
52 EXPECT_TRUE(result.ok()); 61 EXPECT_TRUE(result.ok());
53 if (result.val) delete result.val; 62 if (result.val) delete result.val;
54 } 63 }
55 { 64 {
56 ModuleResult result = DecodeModule(data, data + 1); 65 ModuleResult result = DecodeModule(data, data + 1);
57 EXPECT_TRUE(result.ok()); 66 EXPECT_TRUE(result.ok());
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 EXPECT_EQ(2055, function->local_float64_count); 465 EXPECT_EQ(2055, function->local_float64_count);
457 466
458 EXPECT_FALSE(function->exported); 467 EXPECT_FALSE(function->exported);
459 EXPECT_FALSE(function->external); 468 EXPECT_FALSE(function->external);
460 469
461 if (result.val) delete result.val; 470 if (result.val) delete result.val;
462 } 471 }
463 472
464 473
465 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { 474 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) {
466 static const byte kCodeStartOffset = 2 + kDeclGlobalSize + 4 + 2 + 17; 475 static const byte kDeclMemorySize = 4;
476 static const byte kCodeStartOffset =
477 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17;
467 static const byte kCodeEndOffset = kCodeStartOffset + 3; 478 static const byte kCodeEndOffset = kCodeStartOffset + 3;
468 479
469 static const byte data[] = { 480 static const byte data[] = {
481 kDeclMemory, 28, 28, 1,
470 // global#0 -------------------------------------------------- 482 // global#0 --------------------------------------------------
471 kDeclGlobals, 1, 0, 0, 0, 0, // name offset 483 kDeclGlobals, 1, 0, 0, 0, 0, // name offset
472 kMemU8, // memory type 484 kMemU8, // memory type
473 0, // exported 485 0, // exported
474 // sig#0 ----------------------------------------------------- 486 // sig#0 -----------------------------------------------------
475 kDeclSignatures, 1, 0, 0, // void -> void 487 kDeclSignatures, 1, 0, 0, // void -> void
476 // func#0 ---------------------------------------------------- 488 // func#0 ----------------------------------------------------
477 kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName, 0, 489 kDeclFunctions, 1, kDeclFunctionLocals | kDeclFunctionName, 0,
478 0, // signature index 490 0, // signature index
479 9, 0, 0, 0, // name offset 491 9, 0, 0, 0, // name offset
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 EXPECT_EQ(5, segment->source_size); 536 EXPECT_EQ(5, segment->source_size);
525 EXPECT_TRUE(segment->init); 537 EXPECT_TRUE(segment->init);
526 538
527 if (result.val) delete result.val; 539 if (result.val) delete result.val;
528 } 540 }
529 } 541 }
530 542
531 543
532 TEST_F(WasmModuleVerifyTest, OneDataSegment) { 544 TEST_F(WasmModuleVerifyTest, OneDataSegment) {
533 const byte data[] = { 545 const byte data[] = {
534 kDeclDataSegments, 546 kDeclMemory, 28, 28, 1, kDeclDataSegments, 1, 0xaa, 0xbb, 0x09,
535 1,
536 0xaa,
537 0xbb,
538 0x09,
539 0, // dest addr 547 0, // dest addr
540 11, 548 11, 0, 0,
541 0,
542 0,
543 0, // source offset 549 0, // source offset
544 3, 550 3, 0, 0,
545 0,
546 0,
547 0, // source size 551 0, // source size
548 1, // init 552 1, // init
549 }; 553 };
550 554
551 { 555 {
556 EXPECT_VERIFIES(data);
552 ModuleResult result = DecodeModule(data, data + arraysize(data)); 557 ModuleResult result = DecodeModule(data, data + arraysize(data));
553 EXPECT_TRUE(result.ok()); 558 EXPECT_TRUE(result.ok());
554 EXPECT_EQ(0, result.val->globals->size()); 559 EXPECT_EQ(0, result.val->globals->size());
555 EXPECT_EQ(0, result.val->functions->size()); 560 EXPECT_EQ(0, result.val->functions->size());
556 EXPECT_EQ(1, result.val->data_segments->size()); 561 EXPECT_EQ(1, result.val->data_segments->size());
557 562
558 WasmDataSegment* segment = &result.val->data_segments->back(); 563 WasmDataSegment* segment = &result.val->data_segments->back();
559 564
560 EXPECT_EQ(0x9bbaa, segment->dest_addr); 565 EXPECT_EQ(0x9bbaa, segment->dest_addr);
561 EXPECT_EQ(11, segment->source_offset); 566 EXPECT_EQ(11, segment->source_offset);
562 EXPECT_EQ(3, segment->source_size); 567 EXPECT_EQ(3, segment->source_size);
563 EXPECT_TRUE(segment->init); 568 EXPECT_TRUE(segment->init);
564 569
565 if (result.val) delete result.val; 570 if (result.val) delete result.val;
566 } 571 }
567 572
568 for (size_t size = 1; size < arraysize(data); size++) { 573 for (size_t size = 5; size < arraysize(data); size++) {
569 // Should fall off end of module bytes. 574 // Should fall off end of module bytes.
570 ModuleResult result = DecodeModule(data, data + size); 575 ModuleResult result = DecodeModule(data, data + size);
571 EXPECT_FALSE(result.ok()); 576 EXPECT_FALSE(result.ok());
572 if (result.val) delete result.val; 577 if (result.val) delete result.val;
573 } 578 }
574 } 579 }
575 580
576 581
577 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { 582 TEST_F(WasmModuleVerifyTest, TwoDataSegments) {
578 const byte data[] = { 583 const byte data[] = {
579 kDeclDataSegments, 584 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07,
580 2,
581 0xee,
582 0xff,
583 0x07,
584 0, // dest addr 585 0, // dest addr
585 9, 586 9, 0, 0,
586 0,
587 0,
588 0, // #0: source offset 587 0, // #0: source offset
589 4, 588 4, 0, 0,
590 0,
591 0,
592 0, // source size 589 0, // source size
593 0, // init 590 0, // init
594 0xcc, 591 0xcc, 0xdd, 0x06,
595 0xdd,
596 0x06,
597 0, // #1: dest addr 592 0, // #1: dest addr
598 6, 593 6, 0, 0,
599 0,
600 0,
601 0, // source offset 594 0, // source offset
602 10, 595 10, 0, 0,
603 0,
604 0,
605 0, // source size 596 0, // source size
606 1, // init 597 1, // init
607 }; 598 };
608 599
609 { 600 {
610 ModuleResult result = DecodeModule(data, data + arraysize(data)); 601 ModuleResult result = DecodeModule(data, data + arraysize(data));
611 EXPECT_TRUE(result.ok()); 602 EXPECT_TRUE(result.ok());
612 EXPECT_EQ(0, result.val->globals->size()); 603 EXPECT_EQ(0, result.val->globals->size());
613 EXPECT_EQ(0, result.val->functions->size()); 604 EXPECT_EQ(0, result.val->functions->size());
614 EXPECT_EQ(2, result.val->data_segments->size()); 605 EXPECT_EQ(2, result.val->data_segments->size());
615 606
616 WasmDataSegment* s0 = &result.val->data_segments->at(0); 607 WasmDataSegment* s0 = &result.val->data_segments->at(0);
617 WasmDataSegment* s1 = &result.val->data_segments->at(1); 608 WasmDataSegment* s1 = &result.val->data_segments->at(1);
618 609
619 EXPECT_EQ(0x7ffee, s0->dest_addr); 610 EXPECT_EQ(0x7ffee, s0->dest_addr);
620 EXPECT_EQ(9, s0->source_offset); 611 EXPECT_EQ(9, s0->source_offset);
621 EXPECT_EQ(4, s0->source_size); 612 EXPECT_EQ(4, s0->source_size);
622 EXPECT_FALSE(s0->init); 613 EXPECT_FALSE(s0->init);
623 614
624 EXPECT_EQ(0x6ddcc, s1->dest_addr); 615 EXPECT_EQ(0x6ddcc, s1->dest_addr);
625 EXPECT_EQ(6, s1->source_offset); 616 EXPECT_EQ(6, s1->source_offset);
626 EXPECT_EQ(10, s1->source_size); 617 EXPECT_EQ(10, s1->source_size);
627 EXPECT_TRUE(s1->init); 618 EXPECT_TRUE(s1->init);
628 619
629 if (result.val) delete result.val; 620 if (result.val) delete result.val;
630 } 621 }
631 622
632 for (size_t size = 1; size < arraysize(data); size++) { 623 for (size_t size = 5; size < arraysize(data); size++) {
633 // Should fall off end of module bytes. 624 // Should fall off end of module bytes.
634 ModuleResult result = DecodeModule(data, data + size); 625 ModuleResult result = DecodeModule(data, data + size);
635 EXPECT_FALSE(result.ok()); 626 EXPECT_FALSE(result.ok());
636 if (result.val) delete result.val; 627 if (result.val) delete result.val;
637 } 628 }
638 } 629 }
639 630
640 631
632 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) {
633 const int dest_addr = 0x100;
634 const byte mem_size_log2 = 15;
635 const int kDataSize = 19;
636
637 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) {
638 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) {
639 byte data[] = {
640 kDeclMemory,
641 mem_size_log2,
642 mem_size_log2,
643 1,
644 kDeclDataSegments,
645 1,
646 U32_LE(dest_addr),
647 U32_LE(source_offset),
648 U32_LE(source_size),
649 1, // init
650 };
651
652 STATIC_ASSERT(kDataSize == arraysize(data));
653
654 if (source_offset < kDataSize && source_size >= 0 &&
655 (source_offset + source_size) <= kDataSize) {
656 EXPECT_VERIFIES(data);
657 } else {
658 EXPECT_FAILURE(data);
659 }
660 }
661 }
662 }
663
664
665 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) {
666 const int source_size = 3;
667 const int source_offset = 11;
668
669 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) {
670 int mem_size = 1 << mem_size_log2;
671
672 for (int dest_addr = mem_size - source_size;
673 dest_addr < mem_size + source_size; dest_addr++) {
674 byte data[] = {
675 kDeclMemory,
676 mem_size_log2,
677 mem_size_log2,
678 1,
679 kDeclDataSegments,
680 1,
681 U32_LE(dest_addr),
682 U32_LE(source_offset),
683 U32_LE(source_size),
684 1, // init
685 };
686
687 if (dest_addr <= (mem_size - source_size)) {
688 EXPECT_VERIFIES(data);
689 } else {
690 EXPECT_FAILURE(data);
691 }
692 }
693 }
694 }
695
696
641 // To make below tests for indirect calls much shorter. 697 // To make below tests for indirect calls much shorter.
642 #define FUNCTION(sig_index, external) \ 698 #define FUNCTION(sig_index, external) \
643 kDeclFunctionImport, static_cast<byte>(sig_index), \ 699 kDeclFunctionImport, static_cast<byte>(sig_index), \
644 static_cast<byte>(sig_index >> 8) 700 static_cast<byte>(sig_index >> 8)
645 701
646 702
647 TEST_F(WasmModuleVerifyTest, OneIndirectFunction) { 703 TEST_F(WasmModuleVerifyTest, OneIndirectFunction) {
648 static const byte data[] = { 704 static const byte data[] = {
649 // sig#0 ------------------------------------------------------- 705 // sig#0 -------------------------------------------------------
650 kDeclSignatures, 1, 0, 0, // void -> void 706 kDeclSignatures, 1, 0, 0, // void -> void
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 kDeclWLL, 1004 kDeclWLL,
949 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa 1005 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa
950 1, 2, 3, 4, // 4 byte section 1006 1, 2, 3, 4, // 4 byte section
951 }; 1007 };
952 EXPECT_FAILURE(data); 1008 EXPECT_FAILURE(data);
953 } 1009 }
954 1010
955 } // namespace wasm 1011 } // namespace wasm
956 } // namespace internal 1012 } // namespace internal
957 } // namespace v8 1013 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-opcodes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698