| Titel | floooh sokol e0832c9 Stack-based Buffer Overflow |
|---|
| Beschreibung | ### Description
We discovered a Stack Buffer Overflow in sokol_gfx.
The crash occurs within _sg_validate_pipeline_desc. The ASAN report indicates a READ of size 4 that overflows a stack-allocated variable (desc_def). This likely happens when the validation logic iterates slightly past the bounds of an array within the sg_pipeline_desc structure stored on the stack.
Vendor confirmed and fixed this vulnerability in commit (b95c524)[https://github.com/floooh/sokol/commit/b95c5245ba357967220c9a860c7578a7487937b0].
### Environment
- OS: Linux x86_64
- Complier: Clang
- Build Configuration: Debug (-O0 -g -fsanitize=address)
- Tools: AddressSanitizer
- Affected Version: `master branch`
### Vulnerability Details
- Target: sokol (sokol_gfx.h)
- Crash Type: Stack-buffer-overflow (Read)
- Location: sokol_gfx.h:22897 (in _sg_validate_pipeline_desc)
- Function: _sg_validate_pipeline_desc(const sg_pipeline_desc* desc)
- Root Cause Analysis: The stack trace shows: sg_make_pipeline -> _sg_init_pipeline -> _sg_validate_pipeline_desc.
In sg_make_pipeline, a local variable sg_pipeline_desc desc_def is declared (allocated on the stack). The validation function receives a pointer to this stack variable. ASan reports: [32, 744) 'desc_def' <== Memory access at offset 744. The code attempts to read 4 bytes exactly at the end of the desc_def structure (offset 744). This suggests an off-by-one error or an incorrect loop bound check where the validator tries to access array[MAX_SIZE] (which is out of bounds) instead of stopping at MAX_SIZE - 1.
### Reproduce
1. Compile the sokol test [harness](https://github.com/oneafter/1212/blob/main/harness.c) with AddressSanitizer enabled (-fsanitize=address -g)
2. Run the fuzzer harness with the attached [repro](https://github.com/oneafter/1212/blob/main/stack1) input:
```
./harness repro
```
ASAN report
```
==19507==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fe2a87002e8 at pc 0x5609c75467ac bp 0x7ffd90c034f0 sp 0x7ffd90c034e8
READ of size 4 at 0x7fe2a87002e8 thread T0
#0 0x5609c75467ab in _sg_validate_pipeline_desc /src/sokol/./sokol_gfx.h:22897:22
#1 0x5609c75467ab in _sg_init_pipeline /src/sokol/./sokol_gfx.h:24281:9
#2 0x5609c7539d7b in sg_make_pipeline /src/sokol/./sokol_gfx.h:25151:9
#3 0x5609c754f497 in fuzz_input /src/sokol/harness_gfx_traditional.c:129:31
#4 0x5609c75534b5 in main /src/sokol/harness_gfx_traditional.c:206:9
#5 0x7fe2aa38f1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#6 0x7fe2aa38f28a in __libc_start_main csu/../csu/libc-start.c:360:3
#7 0x5609c743da64 in _start (/src/sokol/harness_gfx_traditional_fuzzer+0x8ba64) (BuildId: 756621c3a83311878fe2c1bf2919da032f4ab964)
Address 0x7fe2a87002e8 is located in stack of thread T0 at offset 744 in frame
#0 0x5609c7539adf in sg_make_pipeline /src/sokol/./sokol_gfx.h:25143
This frame has 1 object(s):
[32, 744) 'desc_def' (line 25146) <== Memory access at offset 744 overflows this variable
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 /src/sokol/./sokol_gfx.h:22897:22 in _sg_validate_pipeline_desc
Shadow bytes around the buggy address:
0x7fe2a8700000: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
0x7fe2a8700080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fe2a8700100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fe2a8700180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fe2a8700200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7fe2a8700280: 00 00 00 00 00 00 00 00 00 00 00 00 00[f3]f3 f3
0x7fe2a8700300: f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3
0x7fe2a8700380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fe2a8700400: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7fe2a8700480: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x7fe2a8700500: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
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
==19507==ABORTING
``` |
|---|
| Quelle | ⚠️ https://github.com/floooh/sokol/issues/1404 |
|---|
| Benutzer | Oneafter (UID 92781) |
|---|
| Einreichung | 19.12.2025 10:39 (vor 4 Monaten) |
|---|
| Moderieren | 21.12.2025 17:38 (2 days later) |
|---|
| Status | Akzeptiert |
|---|
| VulDB Eintrag | 337719 [floooh sokol bis 5d11344150973f15e16d3ec4ee7550a73fb995e0 sokol_gfx.h _sg_validate_pipeline_desc Pufferüberlauf] |
|---|
| Punkte | 20 |
|---|