82 lines
3.5 KiB
Plaintext
82 lines
3.5 KiB
Plaintext
----------------------------------------------------------------------
|
|
Patch name: patch.virtual-addr-checks-overflow
|
|
Author: Bryce Denney
|
|
Date: Tue Oct 2 12:58:18 EDT 2001
|
|
RCS Id: $Id: patch.virtual-addr-checks-overflow,v 1.2 2001-10-03 01:52:17 bdenney Exp $
|
|
|
|
Detailed description:
|
|
Bochs has been crashing in some cases when you try to access data which
|
|
overlaps the segment limit, when the segment limit is near the 32-bit
|
|
boundary. The example that came up a few times is reading/writing 4 bytes
|
|
starting at 0xffffffff when the segment limit was 0xffffffff. The
|
|
condition used to compare offset+length-1 with the limit, but offset+length-1
|
|
was overflowing so the comparison went wrong. This patch changes the
|
|
condition so that it supports all segment limits.
|
|
|
|
Patch was created with:
|
|
cvs diff -u
|
|
Apply patch to what version:
|
|
cvs from october 2, 2001
|
|
Instructions:
|
|
To patch, go to main bochs directory.
|
|
Type "patch -p0 < THIS_PATCH_FILE".
|
|
----------------------------------------------------------------------
|
|
Index: cpu/access.cc
|
|
===================================================================
|
|
RCS file: /cvsroot/bochs/bochs/cpu/access.cc,v
|
|
retrieving revision 1.10
|
|
retrieving revision 1.11
|
|
diff -u -r1.10 -r1.11
|
|
--- cpu/access.cc 2001/10/02 20:01:29 1.10
|
|
+++ cpu/access.cc 2001/10/03 01:06:31 1.11
|
|
@@ -71,7 +71,8 @@
|
|
return;
|
|
|
|
case 2: case 3: /* read/write */
|
|
- if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
|
+ if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
|
|
+ || (length-1 > seg->cache.u.segment.limit_scaled)) {
|
|
BX_INFO(("write_virtual_checks(): write beyond limit, r/w"));
|
|
exception(int_number(seg), 0, 0);
|
|
return;
|
|
@@ -97,7 +98,8 @@
|
|
}
|
|
|
|
else { /* real mode */
|
|
- if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
|
|
+ if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
|
|
+ || (length-1 > seg->cache.u.segment.limit_scaled)) {
|
|
//BX_INFO(("write_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
|
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
|
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|
|
@@ -136,7 +138,8 @@
|
|
case 0: case 1: /* read only */
|
|
case 10: case 11: /* execute/read */
|
|
case 14: case 15: /* execute/read-only, conforming */
|
|
- if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
|
+ if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
|
|
+ || (length-1 > seg->cache.u.segment.limit_scaled)) {
|
|
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
|
exception(int_number(seg), 0, 0);
|
|
return;
|
|
@@ -144,7 +147,8 @@
|
|
break;
|
|
|
|
case 2: case 3: /* read/write */
|
|
- if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
|
|
+ if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
|
|
+ || (length-1 > seg->cache.u.segment.limit_scaled)) {
|
|
BX_INFO(("read_virtual_checks(): write beyond limit"));
|
|
exception(int_number(seg), 0, 0);
|
|
return;
|
|
@@ -191,7 +195,8 @@
|
|
}
|
|
|
|
else { /* real mode */
|
|
- if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
|
|
+ if (offset > (seg->cache.u.segment.limit_scaled - length + 1)
|
|
+ || (length-1 > seg->cache.u.segment.limit_scaled)) {
|
|
//BX_ERROR(("read_virtual_checks() SEG EXCEPTION: %x:%x + %x",
|
|
// (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
|
|
if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
|