-
Notifications
You must be signed in to change notification settings - Fork 637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SECURITY: Heap-based buffer overflow (libpng 1.6.43) #612
Comments
Please post the machine generated file "pnglibconf.h" from your build of libpng. Also please state the version of zlib (or zlib-ng etc) you are using and whether you have modified it. @ctruta: good idea to make this a requirement. Check out the rules for posting bugs on gentoo, they head off issues like "did you manage to cancel MEMALIGN" as in this case. |
File pnglibconf.h: /* libpng version 1.6.43 */ /* Copyright (c) 2018-2024 Cosmin Truta / /* This code is released under the libpng license. / /* pnglibconf.h / zlib version: 1.3.1 |
ALIGNED_MEMORY_SUPPORTED libpng-1.6.43 does a png_error 'incorrect header check' in pngrutil.c when starting to read the IDAT chunk. It's a 'png_chunk_error' so it can't be avoided. The message is coming from png_ptr->zstream.msg (i.e. it is a zlib errror). It's a 1x1 image, 'rowbytes' is 4 (RGBA). png_ptr->height is 1 and the image is not interlaced. The test case does a png_error in the very first call to png_read_IDAT_data (as would be expected). png_read_row never gets to the memcpy; it's immediately after the png_read_IDAT_data call. @Kerkroups there is something wrong with your png_error callback implementation. PLease supply a test program if you think this analysis is wrong. @ctruta: provisional label: "invalid" |
Test program code: #include <png.h> // Error handler for libpng int process_png_file(const char *filename) {
} int main(int argc, char *argv[]) {
} |
@Kerkroups That program does not even get to the If I modify the program to ignore the CRC error then it errors out with the libpng error: IDAT: incorrect header chunk error. You should be seeing the CRC error and the program should exit then. Since it doesn't whatever happens afterwards is down to invalid error handling. Also please put code in a |
@jbowler Thank you for help, it seems that is invalid error handling. |
@ctruta: confirmed invalid |
I can do it, after I look into how to do it. But @jbowler, I think you should be able to do it, too, with your membership rights. (If you can't, please let me know.) |
Roger that. |
During fuzzing process have found heap-based buffer overflow.
AFL output:
`==340876==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000018 at pc 0x55555558e466 bp 0x7fffffffda80 sp 0x7fffffffd240
WRITE of size 32 at 0x502000000018 thread T0
0x55555558e465 in __interceptor_memcpy (fuzzing_libpng/fuzz_libpng+0x3a465) (BuildId: 8fef77cdbc5aaa656761cf421ce6033222be80a6)
0x7ffff7f8f21c (/lib/x86_64-linux-gnu/libpng16.so.16+0x1d21c) (BuildId: b6cb6efa3c76088fb6dd86f16ee702be4d3729b2)
0x7ffff7f8223c in png_read_row (/lib/x86_64-linux-gnu/libpng16.so.16+0x1023c) (BuildId: b6cb6efa3c76088fb6dd86f16ee702be4d3729b2)
0x7ffff7f83cd8 in png_read_image (/lib/x86_64-linux-gnu/libpng16.so.16+0x11cd8) (BuildId: b6cb6efa3c76088fb6dd86f16ee702be4d3729b2)
0x5555556492d8 in LLVMFuzzerTestOneInput /fuzzing_libpng/fuzz_libpng.c:90:5
0x555555649823 in main /fuzzing_libpng/fuzz_libpng.c:140:5
0x7ffff7c8edb9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
0x7ffff7c8ee74 in __libc_start_main csu/../csu/libc-start.c:360:3
0x555555572490 in _start (/fuzzing_libpng/fuzz_libpng+0x1e490) (BuildId: 8fef77cdbc5aaa656761cf421ce6033222be80a6)
0x502000000018 is located 0 bytes after 8-byte region [0x502000000010,0x502000000018)
allocated by thread T0 here:
0x55555560d0e2 in __interceptor_malloc (fuzzing_libpng/fuzz_libpng+0xb90e2) (BuildId: 8fef77cdbc5aaa656761cf421ce6033222be80a6)
0x555555649251 in LLVMFuzzerTestOneInput /fuzzing_libpng/fuzz_libpng.c:86:38
0x555555649823 in main /fuzzing_libpng/fuzz_libpng.c:140:5
SUMMARY: AddressSanitizer: heap-buffer-overflow (/fuzzing_libpng/fuzz_libpng+0x3a465) (BuildId: 8fef77cdbc5aaa656761cf421ce6033222be80a6) in __interceptor_memcpy
Shadow bytes around the buggy address:
0x501ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x501ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x501ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x501fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x501fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x502000000000: fa fa 00[fa]fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x502000000080: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x502000000100: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x502000000180: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x502000000200: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x502000000280: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
Ihis specific issue happens during a call to memcpy, triggered in the png_read_row function from libpng (https://github.com/pnggroup/libpng/blob/d3cf9b6e22fca25273e87d0b11882a7f886c97fe/pngread.c#L559)
memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);)`The function memcpy copies row_info.rowbytes + 1 bytes from png_ptr->row_buf to png_ptr->prev_row.
If png_ptr->prev_row is not properly allocated with at least row_info.rowbytes + 1 bytes, this would lead to copying more data than the destination buffer (prev_row) can hold. This causes a heap buffer overflow.
Payloads that trigger overflow:
The text was updated successfully, but these errors were encountered: