pboettch/libwab

libwab heap-based out-of-bound read in output_subrecord

xinali opened this issue · 0 comments

I recently used your wab parser to parse some wab files, and found some issues.

test on

ubuntu 16.04 x64
compile with clang-6.0

gdb info

Program received signal SIGSEGV, Segmentation fault.
0x0000000000411464 in output_subrecord (vb=0x647400, opno=23, wrec=<optimized out>, prefix=0x43853d "ou", suffix=0x4386cf "\n") at /home/libwab/libwab.c:1092
1092                            output_srec_data( vb, opcode & 0xffff, srec->data, *srec->len, prefix, suffix );
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────────
 RAX  0x17
 RBX  0x647400 ◂— 0x1
 RCX  0x45
 RDX  0x0
 RDI  0x647400 ◂— 0x1
 RSI  0x1f
 R8   0x43853d ◂— outsd  dx, dword ptr [rsi] /* 'ou' */
 R9   0x4386cf ◂— or     al, byte ptr [rax] /* '\n' */
 R10  0x0
 R11  0x0
 R12  0x647a88 ◂— 0x0
 R13  0x7ffff7dd2620 (_IO_2_1_stdout_) ◂— 0xfbad2a84
 R14  0x43853d ◂— outsd  dx, dword ptr [rsi] /* 'ou' */
 R15  0x1
 RBP  0x17
 RSP  0x7fffffffe010 ◂— 0x0
 RIP  0x411464 (output_subrecord+3012) ◂— movsxd rcx, dword ptr [r11]
─────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────
 ► 0x411464 <output_subrecord+3012>    movsxd rcx, dword ptr [r11]
   0x411467 <output_subrecord+3015>    add    rsp, 0x28
   0x41146b <output_subrecord+3019>    pop    rbx
   0x41146c <output_subrecord+3020>    pop    rbp
   0x41146d <output_subrecord+3021>    pop    r12
   0x41146f <output_subrecord+3023>    pop    r13
   0x411471 <output_subrecord+3025>    pop    r14
   0x411473 <output_subrecord+3027>    pop    r15
   0x411475 <output_subrecord+3029>    jmp    output_srec_data <0x410210>
    ↓
   0x410210 <output_srec_data>         lea    rsp, [rsp - 0x98]
   0x410218 <output_srec_data+8>       mov    qword ptr [rsp], rdx
──────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────────────
In file: /home/libwab/libwab.c
   1087                 case MT_EMBEDDED:
   1088                 case MT_STRING:
   1089                 case MT_UNICODE:
   1090                 case MT_SYSTIME:
   1091                 case MT_BINARY:
 ► 1092                         output_srec_data( vb, opcode & 0xffff, srec->data, *srec->len, prefix, suffix );
   1093                         break;
   1094 
   1095                 case MT_UNICODE_ARRAY:
   1096                 {
   1097                         int size,i;
──────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffe010 ◂— 0x0
01:00080x7fffffffe018 —▸ 0x4386cf ◂— or     al, byte ptr [rax] /* '\n' */
... ↓
03:00180x7fffffffe028 ◂— 0xdee6f1e200003a19
04:00200x7fffffffe030 ◂— 0x0
05:00280x7fffffffe038 ◂— 0x17
06:00300x7fffffffe040 ◂— 0x5c /* '\\' */
07:00380x7fffffffe048 —▸ 0x7fffffffe0e0 ◂— 0x100000001
────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────
 ► f 0           411464 output_subrecord+3012
   f 1           412843 write_ldif+2531
   f 2           415da9 output_records+1449
   f 3           403346 main+982
   f 4     7ffff7a2d830 __libc_start_main+240
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address 0x0)
pwndbg> bt
#0  0x0000000000411464 in output_subrecord (vb=0x647400, opno=23, wrec=<optimized out>, prefix=0x43853d "ou", suffix=0x4386cf "\n") at /home/libwab/libwab.c:1092
#1  0x0000000000412843 in write_ldif (dest=0x7ffff7dd2620 <_IO_2_1_stdout_>, mrec=mrec@entry=0x7fffffffe0e0) at /home/libwab/libwab.c:608
#2  0x0000000000415da9 in output_records (wh=wh@entry=0x645e10) at /home/libwab/libwab.c:1329
#3  0x0000000000403346 in main (argc=1, argc@entry=2, argv=0x7fffffffe280, argv@entry=0x7fffffffe278) at /home/libwab/wabread.c:77
#4  0x00007ffff7a2d830 in __libc_start_main (main=0x402f70 <main>, argc=2, argv=0x7fffffffe278, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe268) at ../csu/libc-start.c:291
#5  0x0000000000403609 in _start ()
pwndbg> p srec
$3 = (struct subrecref *) 0x647a88
pwndbg> p *srec
$4 = {
  len = 0x0, 
  acnt = 0x0, 
  data = 0x0
}
pwndbg> info proc mappings                                                                                                                                                   
process 191776
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
            0x400000           0x43c000    0x3c000        0x0 /home/libwab/build/wabread
            0x63b000           0x63c000     0x1000    0x3b000 /home/libwab/build/wabread
            0x63c000           0x63d000     0x1000    0x3c000 /home/libwab/build/wabread
            0x63d000           0x65e000    0x21000        0x0 [heap]
      0x7ffff7809000     0x7ffff780c000     0x3000        0x0 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
      0x7ffff780c000     0x7ffff7a0b000   0x1ff000     0x3000 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
      0x7ffff7a0b000     0x7ffff7a0c000     0x1000     0x2000 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
      0x7ffff7a0c000     0x7ffff7a0d000     0x1000     0x3000 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
      0x7ffff7a0d000     0x7ffff7bcd000   0x1c0000        0x0 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7bcd000     0x7ffff7dcd000   0x200000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dcd000     0x7ffff7dd1000     0x4000   0x1c0000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dd1000     0x7ffff7dd3000     0x2000   0x1c4000 /lib/x86_64-linux-gnu/libc-2.23.so
      0x7ffff7dd3000     0x7ffff7dd7000     0x4000        0x0 
      0x7ffff7dd7000     0x7ffff7dfd000    0x26000        0x0 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7fef000     0x7ffff7ff2000     0x3000        0x0 
      0x7ffff7ff4000     0x7ffff7ffb000     0x7000        0x0 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
      0x7ffff7ffb000     0x7ffff7ffc000     0x1000        0x0 [vdso]
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x25000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x26000 /lib/x86_64-linux-gnu/ld-2.23.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
      0x7ffffffea000     0x7ffffffff000    0x15000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]