-
-
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.
The application attempts to read 195,843 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__bmp_load (via stbi__malloc_mad3) 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/format derived from the parsing step. It attempts to copy 195843 bytes from this 1-byte source buffer. This suggests a discrepancy between the buffer size actually decoded/allocated by stb_image (likely due to a malformed BMP header or RLE compression edge case) and the expected size calculated by bimg logic. bimg fails to verify if the source pointer contains enough data before copying.
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
==63478==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000000011 at pc 0x55bbd116d34f bp 0x7fff76995830 sp 0x7fff76994ff0
READ of size 195843 at 0x502000000011 thread T0
#0 0x55bbd116d34e in __asan_memcpy (/src/bgfx/harness+0xe334e) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d)
#1 0x55bbd140b3f4 in bx::memCopy(void*, void const*, unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bx/src/bx.cpp:121:3
#2 0x55bbd1358a7f 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 0x55bbd12245cc 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 0x55bbd121f099 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 0x55bbd11b34a5 in main /src/bgfx/harness.cpp:32:39
#6 0x7f31068501c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0x7f310685028a in __libc_start_main csu/../csu/libc-start.c:360:3
#8 0x55bbd10cf7f4 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 0x55bbd116f623 in malloc (/src/bgfx/harness+0xe5623) (BuildId: a2ed5e3f73ed170e14adb779fac52e140093e79d)
#1 0x55bbd1275613 in lodepng_malloc(unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/src/image_decode.cpp:43:9
#2 0x55bbd1275613 in stbi__malloc(unsigned long) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:986:12
#3 0x55bbd1275613 in stbi__malloc_mad3(int, int, int, int) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:1057:11
#4 0x55bbd1275613 in stbi__bmp_load(stbi__context*, int*, int*, int*, int, stbi__result_info*) /src/bgfx/.build/projects/gmake-linux-clang/../../../../bimg/3rdparty/stb/stb_image.h:5594:22
#5 0x55bbd1275613 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:1149:35
#6 0x55bbd1263b94 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 fa fa fa fa fa 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
==63478==ABORTING