mirror of https://github.com/bochs-emu/Bochs
- back out my poorly written patch.virtual-address-checks-overflow
This commit is contained in:
parent
d5ecddc64c
commit
6a1c01c8b5
|
@ -33,30 +33,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// In write_virtual_checks and read_virtual_checks, we check that the
|
|
||||||
// segment limit is not between 0 and 4. The reason for this restriction
|
|
||||||
// is that the condition which is used to check for out-of-bounds reads and
|
|
||||||
// writes is:
|
|
||||||
// offset > seg->cache.u.segment.limit_scaled-length+1
|
|
||||||
// This condition works better than the previous one, which overflowed and
|
|
||||||
// failed when offset+length-1 was larger than 0xffffffff. However our new
|
|
||||||
// condition can underflow if the segment limit is less than 4, but hopefully
|
|
||||||
// nobody will want to do that. To be safe though, I added this function
|
|
||||||
// that will panic if anyone tries to set the segment limit less than 4. If
|
|
||||||
// this panic shows up in real software and we must support it, it's not hard
|
|
||||||
// check for overflow/underflow in the condition, but it does add a few
|
|
||||||
// instructions to a heavily used function.
|
|
||||||
//
|
|
||||||
// This is called whenever the segment limit is changed to a non-constant
|
|
||||||
// value. If it's getting set to 0xffff or something, I didn't bother to
|
|
||||||
// call the check function.
|
|
||||||
void
|
|
||||||
BX_CPU_C::check_seg_limit_scaled (char *name, Bit32u value)
|
|
||||||
{
|
|
||||||
if (value >= 0 && value < 4) {
|
|
||||||
BX_PANIC (("segment limit (value=%d, context=%s) is less than 4, which is not supported. See cpu/access.cc", value, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -95,7 +71,7 @@ BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2: case 3: /* read/write */
|
case 2: case 3: /* read/write */
|
||||||
if ( offset > seg->cache.u.segment.limit_scaled-length+1 ) {
|
if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
||||||
BX_INFO(("write_virtual_checks(): write beyond limit, r/w"));
|
BX_INFO(("write_virtual_checks(): write beyond limit, r/w"));
|
||||||
exception(int_number(seg), 0, 0);
|
exception(int_number(seg), 0, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -121,7 +97,7 @@ BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
else { /* real mode */
|
else { /* real mode */
|
||||||
if (offset > seg->cache.u.segment.limit_scaled-length+1) {
|
if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
|
||||||
//BX_INFO(("write_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
//BX_INFO(("write_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
||||||
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
||||||
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|
||||||
|
@ -160,7 +136,7 @@ BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
|
||||||
case 0: case 1: /* read only */
|
case 0: case 1: /* read only */
|
||||||
case 10: case 11: /* execute/read */
|
case 10: case 11: /* execute/read */
|
||||||
case 14: case 15: /* execute/read-only, conforming */
|
case 14: case 15: /* execute/read-only, conforming */
|
||||||
if ( offset > seg->cache.u.segment.limit_scaled-length+1 ) {
|
if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
||||||
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
||||||
exception(int_number(seg), 0, 0);
|
exception(int_number(seg), 0, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +144,7 @@ BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: case 3: /* read/write */
|
case 2: case 3: /* read/write */
|
||||||
if ( offset > seg->cache.u.segment.limit_scaled-length+1 ) {
|
if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
||||||
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
||||||
exception(int_number(seg), 0, 0);
|
exception(int_number(seg), 0, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -215,7 +191,7 @@ BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
else { /* real mode */
|
else { /* real mode */
|
||||||
if ( offset > seg->cache.u.segment.limit_scaled-length+1) {
|
if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
|
||||||
//BX_ERROR(("read_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
//BX_ERROR(("read_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
||||||
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
||||||
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|
||||||
|
|
|
@ -1378,7 +1378,6 @@ public: // for now...
|
||||||
BX_SMF void revalidate_prefetch_q(void);
|
BX_SMF void revalidate_prefetch_q(void);
|
||||||
BX_SMF void invalidate_prefetch_q(void);
|
BX_SMF void invalidate_prefetch_q(void);
|
||||||
|
|
||||||
BX_SMF void check_seg_limit_scaled (char *name, Bit32u value);
|
|
||||||
BX_SMF void write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
|
BX_SMF void write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
|
||||||
BX_SMF void read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
|
BX_SMF void read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
|
||||||
BX_SMF void write_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
|
BX_SMF void write_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
|
||||||
|
|
|
@ -687,7 +687,7 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("CS", BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
// SS:
|
// SS:
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
|
||||||
|
@ -718,7 +718,7 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("SS", BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
// DS:
|
// DS:
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
|
||||||
|
@ -749,7 +749,8 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("DS", BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
|
|
||||||
// ES:
|
// ES:
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
|
||||||
|
@ -780,7 +781,7 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("ES", BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
// FS:
|
// FS:
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
|
||||||
|
@ -811,7 +812,7 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("FS", BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
// GS:
|
// GS:
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
|
||||||
|
@ -842,7 +843,6 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||||
else
|
else
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
|
||||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
|
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("GS", BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled);
|
|
||||||
|
|
||||||
// LDTR:
|
// LDTR:
|
||||||
BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
|
BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
|
||||||
|
|
|
@ -382,7 +382,6 @@ BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
|
||||||
temp->u.segment.limit_scaled = temp->u.segment.limit;
|
temp->u.segment.limit_scaled = temp->u.segment.limit;
|
||||||
|
|
||||||
temp->valid = 1;
|
temp->valid = 1;
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("unknown", temp->u.segment.limit_scaled);
|
|
||||||
}
|
}
|
||||||
else { // system & gate segment descriptors
|
else { // system & gate segment descriptors
|
||||||
switch ( temp->type ) {
|
switch ( temp->type ) {
|
||||||
|
@ -454,7 +453,6 @@ BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
|
||||||
(unsigned) temp->type));
|
(unsigned) temp->type));
|
||||||
temp->valid = 0;
|
temp->valid = 0;
|
||||||
}
|
}
|
||||||
BX_CPU_THIS_PTR check_seg_limit_scaled ("unknown", temp->u.tss386.limit_scaled);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue