thorfdbg / libjpeg

A complete implementation of 10918-1 (JPEG) coming from jpeg.org (the ISO group) with extensions for HDR, lossless and alpha channel coding standardized as ISO/IEC 18477 (JPEG XT).
327 stars 81 forks source link

Stack Buffer Overflow in Function 'Reconstruct' #90

Closed joshuay2022 closed 10 months ago

joshuay2022 commented 10 months ago

Hi, I found a bug related to stack buffer overflow in function 'Reconstruct' in source file 'cmd/reconstruct.cpp'.

Environment

Commit: latest 9e0cea2. OS and architecture: Ubuntu 22.04, x86_64 Compiler: Ubuntu clang version 14.0.0-1ubuntu1.1 Compiling: CC="clang -fsanitize=address -O1 -fno-omit-frame-pointer -g", CXX="clang++ -fsanitize=address -O1 -fno-omit-frame-pointer -g" Program command: ./jpeg -oz -h -s 1x1,2x2,2x2 $poc /dev/null PoC: poc.zip

ASan Output

=================================================================
==31647==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff68981eb4 at pc 0x55bf57095801 bp 0x7fff68981df0 sp 0x7fff68981de8
READ of size 1 at 0x7fff68981eb4 thread T0
    #0 0x55bf57095800 in Reconstruct(char const*, char const*, int, char const*, bool) /root/projects/libjpeg/cmd/reconstruct.cpp:245:37
    #1 0x55bf57086461 in main /root/projects/libjpeg/cmd/main.cpp:747:5
    #2 0x7fb4b2837d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 203de0ae33b53fee1578b117cb4123e85d0534f0)
    #3 0x7fb4b2837e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 203de0ae33b53fee1578b117cb4123e85d0534f0)
    #4 0x55bf56fc3454 in _start (/root/projects/libjpeg/obj-bin/jpeg+0x78454) (BuildId: 010735123ae5ef3ec44058b4380e3db22e0f9cdb)

Address 0x7fff68981eb4 is located in stack of thread T0 at offset 180 in frame
    #0 0x55bf5709416f in Reconstruct(char const*, char const*, int, char const*, bool) /root/projects/libjpeg/cmd/reconstruct.cpp:70

  This frame has 14 object(s):
    [32, 56) 'filehook' (line 73)
    [96, 144) 'tags' (line 77)
    [176, 180) 'subx' (line 122) <== Memory access at offset 180 overflows this variable
    [192, 196) 'suby' (line 122)
    [208, 272) 'atags' (line 123)
    [304, 496) 'itags' (line 129)
    [560, 696) 'bmm' (line 196)
    [768, 1024) 'headername' (line 236)
    [1088, 1344) 'rawname' (line 236)
    [1408, 1432) 'bmhook' (line 264)
    [1472, 1496) 'alphahook' (line 265)
    [1536, 1696) 'tags210' (line 275)
    [1760, 1888) 'tags279' (line 309)
    [1920, 1928) 'error' (line 360)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /root/projects/libjpeg/cmd/reconstruct.cpp:245:37 in Reconstruct(char const*, char const*, int, char const*, bool)
Shadow bytes around the buggy address:
  0x10006d128380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006d128390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006d1283a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006d1283b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10006d1283c0: f1 f1 f1 f1 00 00 00 f2 f2 f2 f2 f2 00 00 00 00
=>0x10006d1283d0: 00 00 f2 f2 f2 f2[04]f2 04 f2 00 00 00 00 00 00
  0x10006d1283e0: 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x10006d1283f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2
  0x10006d128400: f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x10006d128410: 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10006d128420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==31647==ABORTING

The vulnerability may not be critical since the related code is in the 'cmd' directory.

thorfdbg commented 10 months ago

This is due to the lazy allocation of the subsampling array. While I fixed it, please use a better method for obtaining the subsampling in production code. First obtain the depth of the image with GetInformation(), then allocate the array, then get the subsampling information.