Stack Overflow Crash Caused by Unbounded Recursive Parsing During Macro Expansion
## Description
Hello, I discovered a stack-overflow crash in `pulldown-latex` while fuzzing.
When processing a crafted input, the parser repeatedly re-enters `<pulldown_latex::parser::InnerParser>::parse` after a macro expansion attempt (`MacroContext::try_expand_in`). This results in deep recursion and eventually triggers a stack overflow abort. May result in DOS
I attach the crashing input as a PoC file (`poc.zip`) to the issue.
## Crash Location
- `src/parser.rs:235:26` (call into `try_expand_in` / macro expansion path)
- `src/parser.rs:243:33` (recursive re-entry into `<pulldown_latex::parser::InnerParser>::parse`)
- `src/parser/macros.rs:130:57`
## Reproduction Code
```rust
use std::{env, fs};
use pulldown_latex::{mathml::push_mathml, Parser, Storage};
fn main() {
let path = env::args().nth(1).unwrap_or_else(|| {
eprintln!("usage: poc <path-to-poc-input>");
std::process::exit(2);
});
let data = fs::read(&path).unwrap_or_else(|e| {
eprintln!("failed to read {}: {}", path, e);
std::process::exit(2);
});
let input = String::from_utf8_lossy(&data);
let storage = Storage::new();
let parser = Parser::new(&input, &storage);
let mut out = String::new();
let config = Default::default();
match push_mathml(&mut out, parser, config) {
Ok(()) => println!("OK (output_len={})", out.len()),
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
}
```
[poc.zip](https://github.com/user-attachments/files/24141993/poc.zip)
## Stack Trace
```text
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2014728==ERROR: AddressSanitizer: stack-overflow on address 0x7fff00c3cfb8 (pc 0x5919fa410785 bp 0x7fff00c3d7f0 sp 0x7fff00c3cfc0 T0)
#0 0x5919fa410785 in __asan_memset /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:67:3
#1 0x5919fa528f43 in build_hasher /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/hash/random.rs:86:9
#2 0x5919fa528f43 in <std::hash::random::RandomState as core::hash::BuildHasher>::hash_one::<&str> /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/hash/mod.rs:700:31
#3 0x5919fa54f2f8 in make_hash<str, std::hash::random::RandomState> /rust/deps/hashbrown-0.16.1/src/map.rs:258:18
#4 0x5919fa54f2f8 in get<&str, pulldown_latex::parser::macros::Definition, std::hash::random::RandomState, alloc::alloc::Global, str> /rust/deps/hashbrown-0.16.1/src/map.rs:1310:24
#5 0x5919fa54f2f8 in get<&str, pulldown_latex::parser::macros::Definition, std::hash::random::RandomState, str> /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/collections/hash/map.rs:914:19
#6 0x5919fa54f2f8 in try_expand_in /home/zx/pulldown-latex/src/parser/macros.rs:130:57
#7 0x5919fa54f2f8 in <pulldown_latex::parser::InnerParser>::parse /home/zx/pulldown-latex/src/parser.rs:235:26
#8 0x5919fa550bb7 in <pulldown_latex::parser::InnerParser>::parse /home/zx/pulldown-latex/src/parser.rs:243:33
#9 0x5919fa550bb7 in <pulldown_latex::parser::InnerParser>::parse /home/zx/pulldown-latex/src/parser.rs:243:33
.............
#250 0x5919fa550bb7 in <pulldown_latex::parser::InnerParser>::parse /home/zx/pulldown-latex/src/parser.rs:243:33
#251 0x5919fa550bb7 in <pulldown_latex::parser::InnerParser>::parse /home/zx/pulldown-latex/src/parser.rs:243:33
SUMMARY: AddressSanitizer: stack-overflow /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/hash/random.rs:86:9 in build_hasher
==2014728==ABORTING
```
0 条评论