-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Open
Labels
Description
Description
We discovered a Heap Buffer Overflow (Read) vulnerability in bimg. The crash occurs in bimg::imageAlloc when bx::memCopy attempts to read data from a buffer returned by stb_image during GIF parsing.
The application attempts to read 248,852 bytes from a buffer that is only 1 byte in size, leading to a massive out-of-bounds read and immediate crash.
Environment
- OS: Linux x86_64
- Complier: Clang
- Build Configuration: Release mode with ASan enabled.
Vulnerability Details
- Target: bimg (used by bgfx)
- Vulnerability Type: Heap-buffer-overflow (READ)
- Function: bimg::imageAlloc -> bx::memCopy
- Location: bimg/src/image.cpp:3338
- Root Cause Analysis: The ASAN report shows the source buffer was allocated in stbi__gif_load (via stbi__malloc) with a size of only 1 byte. However, the bimg::imageAlloc function calculates the size of the image data to copy based on the image dimensions derived from the GIF metadata. It attempts to copy 248,852 bytes from this 1-byte source buffer. This indicates that bimg does not validate if the buffer returned by stb_image (specifically for GIF files) actually contains the amount of data expected by the image dimensions before performing the memory copy.
Reproduce
- Build bgfx with Release optimization and ASAN enabled.
- Compile the bgfx harness with AddressSanitizer enabled (-fsanitize=address -g)
- Run with the crashing file repro:
./harness < repro
ASAN report
==63587==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000011 at pc 0x55f85c9ff34f bp 0x7ffc6942af10 sp 0x7ffc6942a6d0
READ of size 248852 at 0x502000000011 thread T0
#0 0x55f85c9ff34e in __asan_memcpy (/src/bgfx/harness+0xe334e) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d)
#1 0x55f85cc9d3f4 in bx::memCopy(void*, void const*, unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bx/src/bx.cpp:121:3
#2 0x55f85cbeaa7f in bimg::imageAlloc(bx::AllocatorI*, bimg::TextureFormat::Enum, unsigned short, unsigned short, unsigned short, unsigned short, bool, bool, void const*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/src/image.cpp:3338:4
#3 0x55f85cab65cc in bimg::imageParseStbImage(bx::AllocatorI*, void const*, unsigned int, bx::Error*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/src/image_decode.cpp:688:28
#4 0x55f85cab1099 in bimg::imageParse(bx::AllocatorI*, void const*, unsigned int, bimg::TextureFormat::Enum, bx::Error*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/src/image_decode.cpp:901:27
#5 0x55f85ca454a5 in main /src/bgfx/harness.cpp:32:39
#6 0x7f06c148d1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0x7f06c148d28a in __libc_start_main csu/../csu/libc-start.c:360:3
#8 0x55f85c9617f4 in _start (/src/bgfx/harness+0x457f4) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d)
0x502000000011 is located 0 bytes after 1-byte region [0x502000000010,0x502000000011)
allocated by thread T0 here:
#0 0x55f85ca01623 in malloc (/src/bgfx/harness+0xe5623) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d)
#1 0x55f85cb0e45c in lodepng_malloc(unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/src/image_decode.cpp:43:9
#2 0x55f85cb0e45c in stbi__malloc(unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:986:12
#3 0x55f85cb0e45c in stbi__gif_load_next(stbi__context*, stbi__gif*, int*, int, unsigned char*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:6790:28
#4 0x55f85cb0e45c in stbi__gif_load(stbi__context*, int*, int*, int*, int, stbi__result_info*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:7052:8
#5 0x55f85cb0e45c in stbi__load_main(stbi__context*, int*, int*, int*, int, stbi__result_info*, int) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:1152:35
#6 0x55f85caf5b94 in stbi__load_and_postprocess_8bit(stbi__context*, int*, int*, int*, int) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:1262:19
SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/bgfx/harness+0xe334e) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d) in __asan_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[01]fa fa fa fd fa fa fa fd fa fa fa fa fa
0x502000000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x502000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x502000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x502000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x502000000280: 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
==63587==ABORTING