Bug 25068 - Several crashes inside libasm
Summary: Several crashes inside libasm
Status: RESOLVED FIXED
Alias: None
Product: elfutils
Classification: Unclassified
Component: libasm (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-10-06 15:08 UTC by leftcopy.chx
Modified: 2019-10-26 00:35 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2019-10-16 00:00:00


Attachments
POCs and error messages (15.38 KB, application/x-bzip)
2019-10-06 15:08 UTC, leftcopy.chx
Details

Note You need to log in before you can comment on or make changes to this bug.
Description leftcopy.chx 2019-10-06 15:08:22 UTC
Created attachment 12023 [details]
POCs and error messages

By applying our fuzzer, we detected several crashes/vulnerabilities on git 47780c9e (HEAD).
The pocs are attached and can be triggered by running `./eu-objdump -d $FILE` when ASAN is enabled.


$ ldd ./eu-objdump
        linux-vdso.so.1 (0x00007ffdbe7d8000)
        libasan.so.4 => /usr/lib/x86_64-linux-gnu/libasan.so.4 (0x00007f71d83ee000)
        libasm.so.1 => /home/hongxu/FOT/Targets/elfutils/eu-asan/install/lib/libasm.so.1 (0x00007f71d81d7000)
        libdw.so.1 => /home/hongxu/FOT/Targets/elfutils/eu-asan/install/lib/libdw.so.1 (0x00007f71d7d9a000)
        libelf.so.1 => /home/hongxu/FOT/Targets/elfutils/eu-asan/install/lib/libelf.so.1 (0x00007f71d7b3f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f71d774e000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f71d754a000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f71d7342000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f71d7123000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f71d6d85000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f71d6b6d000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f71d6950000)
        liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f71d672a000)
        libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f71d651a000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f71d96cd000)
Comment 1 Mark Wielaard 2019-10-16 13:21:53 UTC
Thanks for the example crashes. These seem caused by 2 asserts, a missing bounds check and an off-by-one bounds check. Which should be resolved by the following patch:

diff --git a/libcpu/i386_data.h b/libcpu/i386_data.h
index b8a34c3e..06356b8a 100644
--- a/libcpu/i386_data.h
+++ b/libcpu/i386_data.h
@@ -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]);
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 8a206398..4422ffa2 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -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;
Comment 2 Mark Wielaard 2019-10-26 00:35:33 UTC
commit 99dc63b10b3878616b85df2dfd2e4e7103e414b8 (HEAD -> master)
Author: Mark Wielaard <mark@klomp.org>
Date:   Sat Oct 19 14:01:30 2019 +0200

    libcpu: Fix bounds checks and replace asserts with errors.
    
    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>