libcpu: Fix bounds checks and replace asserts with errors.
authorMark Wielaard <mark@klomp.org>
Sat, 19 Oct 2019 12:01:30 +0000 (14:01 +0200)
committerMark Wielaard <mark@klomp.org>
Sat, 26 Oct 2019 00:28:48 +0000 (02:28 +0200)
Add a missing bounds check, fix an off-by-one bounds check and replace
asserts with error messages.

https://sourceware.org/bugzilla/show_bug.cgi?id=25068

Signed-off-by: Mark Wielaard <mark@klomp.org>
libcpu/ChangeLog
libcpu/i386_data.h
libcpu/i386_disasm.c

index e23097b..52567be 100644 (file)
@@ -1,3 +1,11 @@
+2019-10-17  Mark Wielaard  <mark@klomp.org>
+
+       * i386_data.h (FCT_sel): Check for param_start + 2 >= end instead
+       of just >.
+       * i386_disasm.c (i386_disasm): Check param_start < end. Don't
+       assert, but assign INVALID to str. Make sure we get past any
+       unrecognized opcode.
+
 2019-09-07  Mark Wielaard  <mark@klomp.org>
 
        * riscv_disasm.c (riscv_disasm): Use UINT64_C to make calculation
index b8a34c3..06356b8 100644 (file)
@@ -1336,7 +1336,7 @@ FCT_sel (struct output_data *d)
 {
   assert (d->opoff1 % 8 == 0);
   assert (d->opoff1 / 8 == 5);
-  if (*d->param_start + 2 > d->end)
+  if (*d->param_start + 2 >= d->end)
     return -1;
   *d->param_start += 2;
   uint16_t absval = read_2ubyte_unaligned (&d->data[5]);
index 8a20639..4422ffa 100644 (file)
@@ -610,7 +610,9 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
 
                  /* Account for displacement.  */
                  if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
-                     || ((modrm & 0xc7) == 0x4 && (codep[0] & 0x7) == 0x5))
+                     || ((modrm & 0xc7) == 0x4
+                         && param_start < end
+                         && (codep[0] & 0x7) == 0x5))
                    param_start += 4;
                  else if ((modrm & 0xc0) == 0x40)
                    param_start += 1;
@@ -821,7 +823,8 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
                            }
                          FALLTHROUGH;
                        default:
-                         assert (! "INVALID not handled");
+                         str = "INVALID not handled";
+                         break;
                        }
                    }
                  else
@@ -1124,8 +1127,9 @@ i386_disasm (Ebl *ebl __attribute__((unused)),
       /* Invalid (or at least unhandled) opcode.  */
       if (prefixes != 0)
        goto print_prefix;
-      assert (*startp == data);
-      ++data;
+      /* Make sure we get past the unrecognized opcode if we haven't yet.  */
+      if (*startp == data)
+       ++data;
       ADD_STRING ("(bad)");
       addr += data - begin;