On Fri, Jul 25, 2025, 01:38 Xudong Cao <[email protected]> wrote:

> ## Description
>
> GNU Bison contains a critical assertion failure in the
> `__obstack_vprintf_internal` function within `obprintf.c:158`. When
> processing specially crafted grammar files containing malformed `$variable`
> references, the program triggers an assertion failure that causes immediate
> program termination with SIGABRT.
>
> ## Technical Analysis
>
> ### Stack Trace
> ```
> #0 __pthread_kill_implementation (no_tid=0, signo=6,
> threadid=140737351530368) at ./nptl/pthread_kill.c:44
> #1 __pthread_kill_internal (signo=6, threadid=140737351530368) at
> ./nptl/pthread_kill.c:78
> #2 __GI___pthread_kill (threadid=140737351530368, signo=signo@entry=6) at
> ./nptl/pthread_kill.c:89
> #3 0x00007ffff7dc8476 in __GI_raise (sig=sig@entry=6) at
> ../sysdeps/posix/raise.c:26
> #4 0x00007ffff7dae7f3 in __GI_abort () at ./stdlib/abort.c:79
> #5 0x00007ffff7dae71b in __assert_fail_base (fmt=0x7ffff7f63130 "%s%s%s:%u:
> %s%sAssertion `%s' failed.\n%n", assertion=0x7ffff7f63c08 "size ==
> (new_f.ofile.file.file._IO_write_end -
> new_f.ofile.file.file._IO_write_base)", file=0x7ffff7f5f416 "obprintf.c",
> line=158, function=<optimized out>) at ./assert/assert.c:94
> #6 0x00007ffff7dbfe96 in __GI___assert_fail
> (assertion=assertion@entry=0x7ffff7f63c08
> "size == (new_f.ofile.file.file._IO_write_end -
> new_f.ofile.file.file._IO_write_base)", file=file@entry=0x7ffff7f5f416
> "obprintf.c", line=line@entry=158, function=function@entry=0x7ffff7f67740
> <__PRETTY_FUNCTION__.1> "__obstack_vprintf_internal") at
> ./assert/assert.c:103
> #7 0x00007ffff7e0e81a in __obstack_vprintf_internal (obstack=0x5555558656c0
> <obstack_for_string>, format=0x55555555fab8 "]b4_lhs_value(orig %d, ",
> args=args@entry=0x7fffffff8200, mode_flags=2) at ./libio/obprintf.c:158
> #8 0x00007ffff7ebc353 in __obstack_printf_chk (obstack=<optimized out>,
> flag=<optimized out>, format=<optimized out>) at ./debug/obprintf_chk.c:34
> #9 0x00005555555f8c8b in handle_action_dollar (rule=0x555555887510,
> text=<optimized out>, dollar_loc=<optimized out>) at src/scan-code.l:661
> #10 code_lex (self=0x5555558875a8, sc_context=<optimized out>) at
> src/scan-code.l:171
> #11 translate_action (self=0x5555558875a8, sc_context=<optimized out>) at
> src/scan-code.l:768
> #12 0x00005555555f8c8b in code_props_translate_code (self=0x5555558875a8)
> #13 0x00005555555f0ffc in check_and_convert_grammar () at src/reader.c:1002
> #14 reader (gram=<optimized out>) at src/reader.c:772
> #15 0x00005555555a4f52 in main (argc=<optimized out>, argv=0x7fffffffdce8)
> at src/main.c:118
> ```
>
> ### Root Cause Analysis
>
> The vulnerability exists in Bison's obstack (object stack) buffer
> management system. During grammar processing, the `handle_action_dollar`
> function calls `obstack_printf` to format output strings. The assertion
> failure occurs when the obstack's internal state becomes inconsistent:
>
> **Failed Assertion**: `size == (new_f.ofile.file.file._IO_write_end -
> new_f.ofile.file.file._IO_write_base)`
>
> This indicates that the difference between `_IO_write_end` and
> `_IO_write_base` pointers does not match the expected buffer size,
> suggesting corruption in the obstack's internal pointer management.
>
> ### Call Chain Analysis
> 1. `main()` → `reader()` → `check_and_convert_grammar()`
> 2. `code_props_translate_code()` → `translate_action()`
> 3. `code_lex()` → `handle_action_dollar()` (src/scan-code.l:661)
> 4. `__obstack_printf_chk()` → `__obstack_vprintf_internal()`
> 5. **Assertion failure** at obprintf.c:158
>
> ## Proof of Concept
>
> The vulnerability can be triggered using the provided POC file:
>
> **File**: `POC_bison_obprintf_assertion_failure`[
>
> https://drive.google.com/file/d/1iId0E6HVYNwqLsS5nARQexj5TQqzcnej/view?usp=drive_link
> ]
>
> **Reproduction Steps**:
> 1. Execute: `bison POC_bison_obprintf_assertion_failure`
> 2. Observe the assertion failure and program crash
> 3. Verify SIGABRT signal is generated
>
> **Expected Output**:
> ```
> bison: obprintf.c:158: __obstack_vprintf_internal: Assertion `size ==
> (new_f.ofile.file.file._IO_write_end -
> new_f.ofile.file.file._IO_write_base)' failed.
> Aborted (core dumped)
> ```
>
> ## Vulnerability Confirmation
>
> This vulnerability has been confirmed through:
> - GDB stack trace analysis showing consistent crash location
> - Multiple POC files triggering identical assertion failures
> - Reproducible crash across different input variations
>
> The assertion failure demonstrates a fundamental buffer management issue in
> Bison's core processing logic, making this a legitimate security
> vulnerability affecting program reliability.
>
> ### Credit
> Xudong Cao (UCAS)
> Yuqing Zhang (UCAS, Zhongguancun Laboratory)
>

Reply via email to