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)
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;
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>