Microsoft's FORGE Lab Lists Rust Standard-Library Soundness Bugs, Several Still Open
Security / news
Microsoft's FORGE Lab Lists Rust Standard-Library Soundness Bugs, Several Still Open
The Nov. 9 post names issues in std and core, some reachable from safe code, and says its own authors judge one of them unlikely to be exploited.

Microsoft's FORGE Lab said Nov. 9 that it found soundness bugs in the unsafe code of Rust's standard library, some of them triggerable from safe Rust. A soundness bug is one where code that the compiler accepts as safe can still cause undefined behaviour, such as a double free. Each needs an unusual setup, and the lab says one becomes a vulnerability only if a real program reaches the API that way.
The post, published on the Microsoft Security Blog under the byline of Yechan Bae and the FORGE Lab team, gives no total bug count and lists no CVE IDs for the new findings. It cites two older ones, CVE-2020-36323 and CVE-2015-20001, and does not say whether FORGE reported them.
What Hyenas did and did not find
Some of the bugs came from Hyenas, which the post describes as FORGE's research version of codename MDASH, an AI-powered vulnerability-scanning system. The post does not describe its internals. It says researchers reproduced each bug, assessed the impact and worked with Rust maintainers on reports and fixes. Some bugs were found without the tool, so Hyenas is not the sole source. Compiler bugs are out of scope.
The issues, by number
| Issue | API | Status per the post |
|---|---|---|
| #156501 | MapWindows::clone | Rust 1.97.0 |
| #156491 | str::replace with a custom Pattern | Rust 1.96.0 |
| #161018 | process::exit and the main thread's signal stack | Rust 1.98.0 |
| #156951 | CommandExt::exec and environ | Fix in review (PR #157144) |
| #158265, #165076 | strip_prefix_of, split_once | Open at publication |
| #164243 | process::exit and thread-local destructors | Open, reported by someone else |
The BTreeMap::insert family (#156490, with #159334, #159368 and #159370 reported by others) concerns allocators that unwind. The post says the Allocator API's stabilization requires implementors not to unwind, and that it ships in Rust 1.100 on Nov. 12.
Two issues read on GitHub
The post is one side of each story, so the issue threads matter. Issue #161018 was opened Aug. 13 by a user named qwaz on behalf of FORGE and closed Aug. 14. Calling process::exit from a non-main thread unmaps the main thread's alternate signal stack without unregistering it, so a later signal on the main thread touches unmapped memory and segfaults. The reporter wrote that exploitation was theoretically possible but practically unlikely, because the race window is tight.
The maintainer who took it, joboet, traced the cause to PR #28069, the change that put the cleanup call in process::exit. joboet wrote that they had "looked at that code countless time, and this never occurred to me," and pointed to an existing FIXME in stack_overflow::cleanup warning that the code might cause more bugs than it was worth. The post dates the bug to 2015.
Issue #164243 is a different reporter's work. Juho Snellman opened it Oct. 13: safe code calling std::process::exit() from a thread-local destructor can double free, and the program aborts with "free(): double free detected in tcache 2." It reproduces on nightly and on stable back to 1.85.0, and it is open with the P-high label. Snellman found it while probing a different project's frontend with Claude Code and verified the reports by hand, the issue says.
The thread shows why this class of bug is slow to close. joboet prefers not to run thread-local destructors on exit, since the thread's stack is not cleaned up either, and said that on macOS this is close to unimplementable because those destructors run before atexit handlers. A contributor, theemathas, wrote that there is no threshold for how unrealistic an unsoundness can be before it is rejected, citing open issue #135011.
Where it fits
The Terminal's piece on Rust pointer provenance covers a neighbouring area where the language's rules and unsafe code meet. For another disclosure that began with a C library overflow, see Hacktron's libheif and SSO chain.
Programmers who call exec, process::exit from threads, or custom Pattern implementations should watch PR #157144 and PR #165125. Both fixes were still unmerged when the post went up.
Sources
More in Security
- 01Zeabur's Report: A Plaintext Admin Token With No Expiry, 16 Hours Without an Alert, 321,810 AccountsThe hosting platform that is closing on Dec. 31 published an hour-by-hour timeline of its October breach and put the root cause on its own credential handling.
- 02Wiz Counts Nine AI Developer Platforms Breached in October, All Aimed at Stored API KeysWiz's roundup finds no shared vulnerability, two Bedrock abuse cases totalling about 2.5 million calls, and root causes that are each platform's own account.
- 03Railway Puts Exposed Variables at 1.85% of Workspaces, About 100,000, After a Build-Infrastructure EscalationThe platform's preliminary report says the attacker was after AI provider keys for distillation, and leaves the entry point unnamed.
- 04Northflank's Timeline Has Secrets Decrypted at 02:39 UTC and the First Alert at 11:43The status page's Nov. 6 update measures its 60-minute patch claim from the alert, not from the start of the decryption window.