Skip to content

[BUG] runtime error in pngfix.c #779

@ShangzhiXu

Description

@ShangzhiXu

Hi team, here's another crash I triggered during fuzzing

PoC

https://github.com/user-attachments/assets/cf2a9648-af4f-44dc-b4df-53bcf5a21e34

Root Cause

In function get32, although buffer is of type png_byte (unsigned char), it is implicitly promoted to int before the shift. When a byte value ≥ 128 is shifted left by 24 bits, the result exceeds the representable range of a signed int, triggering undefined behavior.
More specifically

buffer[i] = 152 (0x98)
→ int 152152 << 24 = 0x98000000

In source code

get32(png_byte *buffer, int offset)
   /* Read a 32-bit value from an 8-byte circular buffer (used only below).
    */
{
   return
      (buffer[ offset    & 7] << 24) + \\ Crash point
      (buffer[(offset+1) & 7] << 16) +
      (buffer[(offset+2) & 7] <<  8) +
      (buffer[(offset+3) & 7]      );
}

Fix

I think maybe we can cast buffer to a more secure type like to avoid the crash. I've tried and it works on my machine

return
   ((uint32_t)buffer[ offset    & 7] << 24) |
   ((uint32_t)buffer[(offset+1) & 7] << 16) |
   ((uint32_t)buffer[(offset+2) & 7] <<  8) |
   ((uint32_t)buffer[(offset+3) & 7]);

Crash

We can compile with

 CFLAGS="-O0 -g \
  -fsanitize=address,undefined \
  -fno-omit-frame-pointer \
  -fno-sanitize-trap=all \
  -no-pie" LDFLAGS="-fsanitize=address,undefined -no-pie" make -j

When we run ~/G2FUZZ/target/libpng-asan/pngfix poc.png

contrib/tools/pngfix.c:2926:31: runtime error: left shift of 152 by 24 places cannot be represented in type 'int'
    #0 0x00000052aebf in get32 /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:2926:31
    #1 0x000000519720 in sync_stream /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3003:46
    #2 0x000000512f26 in read_chunk /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3131:4
    #3 0x00000050c9b9 in read_callback /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3252:10
    #4 0x00000058bb8f in png_read_data /home/z5500277/G2FUZZ/target/libpng-asan/pngrio.c:36:7
    #5 0x0000005f627e in png_read_chunk_header /home/z5500277/G2FUZZ/target/libpng-asan/pngrutil.c:196:4
    #6 0x00000056252a in png_read_info /home/z5500277/G2FUZZ/target/libpng-asan/pngread.c:118:28
    #7 0x000000508744 in read_png /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3588:7
    #8 0x000000507804 in one_file /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3636:12
    #9 0x000000506c09 in main /home/z5500277/G2FUZZ/target/libpng-asan/contrib/tools/pngfix.c:3986:16
    #10 0x7fbcf71717e4 in __libc_start_main (/lib64/libc.so.6+0x3a7e4) (BuildId: 9846edf82646848f2857c47c5a2eb71c288059ec)
    #11 0x00000042a50d in _start (/home/z5500277/G2FUZZ/target/libpng-asan/pngfix+0x42a50d) (BuildId: e8887aced306f586853c9084c74b3b22962b9e15)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions