Yeraze / ytnef

Yeraze's TNEF Stream Reader - for winmail.dat files
GNU General Public License v2.0
32 stars 22 forks source link

OOB access in function ProcessTNEF() in main.c #92

Closed chibataiki closed 3 years ago

chibataiki commented 3 years ago

Hi, A OOB access can be triggered in latest commit 216377b.

The data might not be NULL-terminated, Size +1 need for the end of string the '\0'

vl->data = calloc(vl->size, sizeof(BYTE));

Test platform:
ubuntu 20.04 x86_64 gcc version 9.3.0

reproduce:

CC=gcc  CFLAGS="-fsanitize=address"  ./configure
make 
./ytnef  poc

oob_poc.zip

Debug info:

ERROR: invalid alloc size 923074563 at ytnef.c : 461, suspected corruption (exceeded 1000 bytes)
=================================================================
==3877672==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040000001f2 at pc 0x0000002717a4 bp 0x7ffce3647680 sp 0x7ffce3646e08
READ of size 35 at 0x6040000001f2 thread T0
    #0 0x2717a3 in printf_common(void*, char const*, __va_list_tag*) (/home/ytnef/bin/ytnef+0x2717a3)
    #1 0x273020 in snprintf (/home/ytnef/bin/ytnef+0x273020)
    #2 0x3030b4 in ProcessTNEF /home/ytnef/ytnef/main.c:381:9
    #3 0x300732 in main /home/ytnef/ytnef/main.c:145:15
    #4 0x7fbe727700b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #5 0x2533ed in _start (/home/ytnef/bin/ytnef+0x2533ed)

0x6040000001f2 is located 0 bytes to the right of 34-byte region [0x6040000001d0,0x6040000001f2)
allocated by thread T0 here:
    #0 0x2cd5d2 in calloc (/home/ytnef/bin/ytnef+0x2cd5d2)
    #1 0x7fbe72af6026 in TNEFFillMapi /home/ytnef/lib/ytnef.c:535:24
    #2 0x7fbe72b057f7 in TNEFParse /home/ytnef/lib/ytnef.c:1221:15
    #3 0x7fbe72b04365 in TNEFParseFile /home/ytnef/lib/ytnef.c:1078:10
    #4 0x3006cb in main /home/ytnef/ytnef/main.c:140:9
    #5 0x7fbe727700b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/ytnef/bin/ytnef+0x2717a3) in printf_common(void*, char const*, __va_list_tag*)
Shadow bytes around the buggy address:
  0x0c087fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c087fff8000: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 06
  0x0c087fff8010: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 02 fa
  0x0c087fff8020: fa fa 00 00 00 00 00 05 fa fa 00 00 00 00 00 07
=>0x0c087fff8030: fa fa 00 00 00 00 00 07 fa fa 00 00 00 00[02]fa
  0x0c087fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==3877672==ABORTING

If built without ASAN, and use Valgrind , maybe more detailed.

==1176416== Memcheck, a memory error detector
==1176416== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1176416== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==1176416== Command: ./bin/ytnef ./crash_verifyed/heap-overflow.1
==1176416==
ERROR: invalid alloc size 923074563 at ytnef.c : 461, suspected corruption (exceeded 1000 bytes)
==1176416== Invalid read of size 1
==1176416==    at 0x483EF54: strlen (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1176416==    by 0x48EBE94: __vfprintf_internal (vfprintf-internal.c:1688)
==1176416==    by 0x48FF119: __vsnprintf_internal (vsnprintf.c:114)
==1176416==    by 0x48D4F75: snprintf (snprintf.c:31)
==1176416==    by 0x10CD50: snprintf (stdio2.h:67)
==1176416==    by 0x10CD50: ProcessTNEF (main.c:381)
==1176416==    by 0x10950B: main (main.c:145)
==1176416==  Address 0x4a72e02 is 0 bytes after a block of size 34 alloc'd
==1176416==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1176416==    by 0x484DB81: TNEFFillMapi (ytnef.c:535)
==1176416==    by 0x484F7FE: TNEFParse (ytnef.c:1221)
==1176416==    by 0x484FAF2: TNEFParseFile (ytnef.c:1078)
==1176416==    by 0x1094E8: main (main.c:140)
==1176416==
==1176416==
==1176416== HEAP SUMMARY:
==1176416==     in use at exit: 0 bytes in 0 blocks
==1176416==   total heap usage: 177 allocs, 177 frees, 45,764 bytes allocated
==1176416==
==1176416== All heap blocks were freed -- no leaks are possible
==1176416==
==1176416== For lists of detected and suppressed errors, rerun with: -s
==1176416== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)