https://gcc.gnu.org/g:a8290fb163443276c3df6b20024c6874f93c560c
commit r16-7746-ga8290fb163443276c3df6b20024c6874f93c560c Author: Ruslan Valiyev <[email protected]> Date: Thu Feb 26 19:15:06 2026 +0000 libiberty: fix resource exhaustion in rust demangler (PR demangler/106641) demangle_binder() parses the bound_lifetimes count as a base-62 integer with no upper bound. A crafted symbol can encode a huge lifetime count in very few bytes, causing OOM or CPU hang. Cap bound_lifetimes at 1024 and check rdm->errored in the loop so it bails out early on errors during iteration. libiberty/ChangeLog: PR demangler/106641 * rust-demangle.c (demangle_binder): Reject bound_lifetimes above 1024 to prevent resource exhaustion from crafted symbols. Add rdm->errored check in the loop condition. * testsuite/rust-demangle-expected: Add regression test. Signed-off-by: Ruslan Valiyev <[email protected]> Diff: --- libiberty/rust-demangle.c | 9 ++++++++- libiberty/testsuite/rust-demangle-expected | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libiberty/rust-demangle.c b/libiberty/rust-demangle.c index 190709996545..013f14eebac3 100644 --- a/libiberty/rust-demangle.c +++ b/libiberty/rust-demangle.c @@ -651,10 +651,17 @@ demangle_binder (struct rust_demangler *rdm) return; bound_lifetimes = parse_opt_integer_62 (rdm, 'G'); + /* Reject implausibly large lifetime counts to prevent + resource exhaustion from crafted symbols (PR demangler/106641). */ + if (bound_lifetimes > 1024) + { + rdm->errored = 1; + return; + } if (bound_lifetimes > 0) { PRINT ("for<"); - for (i = 0; i < bound_lifetimes; i++) + for (i = 0; i < bound_lifetimes && !rdm->errored; i++) { if (i > 0) PRINT (", "); diff --git a/libiberty/testsuite/rust-demangle-expected b/libiberty/testsuite/rust-demangle-expected index b565084cfefa..acadf7c9b83b 100644 --- a/libiberty/testsuite/rust-demangle-expected +++ b/libiberty/testsuite/rust-demangle-expected @@ -321,3 +321,9 @@ foo --format=rust _RNvC9backtrace3foo.llvm.A5310EB9 backtrace::foo +# +# PR demangler/106641: crafted symbol with huge lifetime count +# should not cause resource exhaustion. +--format=rust +_RINvC4te_C4tokpppppppppppFFFFFFGFpppppppppKj2_FFFFFFFFFFFFFE +_RINvC4te_C4tokpppppppppppFFFFFFGFpppppppppKj2_FFFFFFFFFFFFFE
