From 9ee351f37fbf78aa408f60c0d2c7ec49e625f109 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 5 Feb 2020 10:33:28 -0800 Subject: 5983 - fix an emulator bounds-check bug It was possible for an instruction to write out of bounds of the memory data structure. Most of the time this worked fine. However if the block ever got resized and moved the out-of-bounds bytes no longer went along. --- 010---vm.cc | 2 +- 013direct_addressing.cc | 2 +- 014indirect_addressing.cc | 2 +- 015immediate_addressing.cc | 2 +- 021byte_addressing.cc | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/010---vm.cc b/010---vm.cc index a0724760..472990a0 100644 --- a/010---vm.cc +++ b/010---vm.cc @@ -108,7 +108,7 @@ struct vma { uint8_t& data(uint32_t a) { assert(match(a)); uint32_t result_index = a-start; - if (_data.size() <= result_index) { + if (_data.size() <= result_index+/*largest word size that can be accessed in one instruction*/sizeof(int)) { const int align = 0x1000; uint32_t result_size = result_index + 1; // size needed for result_index to be valid uint32_t new_size = align_upwards(result_size, align); diff --git a/013direct_addressing.cc b/013direct_addressing.cc index 38e00665..729b4d08 100644 --- a/013direct_addressing.cc +++ b/013direct_addressing.cc @@ -986,7 +986,7 @@ case 0x89: { // copy r32 to r/m32 const uint8_t rsrc = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "copy " << rname(rsrc) << " to r/m32" << end(); int32_t* dest = effective_address(modrm); - *dest = Reg[rsrc].i; + *dest = Reg[rsrc].i; // Write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *dest << end(); break; } diff --git a/014indirect_addressing.cc b/014indirect_addressing.cc index 9c50c129..19d4d509 100644 --- a/014indirect_addressing.cc +++ b/014indirect_addressing.cc @@ -818,7 +818,7 @@ case 0x8f: { // pop stack into r/m32 case 0: { trace(Callstack_depth+1, "run") << "pop into r/m32" << end(); int32_t* dest = effective_address(modrm); - *dest = pop(); + *dest = pop(); // Write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. break; } } diff --git a/015immediate_addressing.cc b/015immediate_addressing.cc index c264d5d3..a2923b7a 100644 --- a/015immediate_addressing.cc +++ b/015immediate_addressing.cc @@ -1235,7 +1235,7 @@ case 0xc7: { // copy imm32 to r32 int32_t* dest = effective_address(modrm); const int32_t src = next32(); trace(Callstack_depth+1, "run") << "imm32 is 0x" << HEXWORD << src << end(); - *dest = src; + *dest = src; // Write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. break; } diff --git a/021byte_addressing.cc b/021byte_addressing.cc index a0b36776..36287e38 100644 --- a/021byte_addressing.cc +++ b/021byte_addressing.cc @@ -68,7 +68,7 @@ case 0x88: { // copy r8 to r/m8 // use unsigned to zero-extend 8-bit value to 32 bits uint8_t* dest = reinterpret_cast(effective_byte_address(modrm)); const uint8_t* src = reg_8bit(rsrc); - *dest = *src; + *dest = *src; // Read/write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); break; } @@ -108,7 +108,7 @@ case 0x8a: { // copy r/m8 to r8 const uint8_t* src = reinterpret_cast(effective_byte_address(modrm)); uint8_t* dest = reg_8bit(rdest); trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*src) << end(); - *dest = *src; + *dest = *src; // Read/write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. const uint8_t rdest_32bit = rdest & 0x3; trace(Callstack_depth+1, "run") << rname(rdest_32bit) << " now contains 0x" << HEXWORD << Reg[rdest_32bit].u << end(); break; @@ -170,7 +170,7 @@ case 0xc6: { // copy imm8 to r/m8 } // use unsigned to zero-extend 8-bit value to 32 bits uint8_t* dest = reinterpret_cast(effective_byte_address(modrm)); - *dest = src; + *dest = src; // Write multiple elements of vector at once. Assumes sizeof(int) == 4 on the host as well. trace(Callstack_depth+1, "run") << "storing 0x" << HEXBYTE << NUM(*dest) << end(); break; } -- cgit 1.4.1-2-gfad0