Skip to content

Fix unwind vulnerability#660

Open
sgued wants to merge 3 commits intorust-embedded:mainfrom
sgued:fix-unwind-vuln
Open

Fix unwind vulnerability#660
sgued wants to merge 3 commits intorust-embedded:mainfrom
sgued:fix-unwind-vuln

Conversation

@sgued
Copy link
Copy Markdown
Contributor

@sgued sgued commented Apr 27, 2026

Fixes #659

Prior to this, a panic in a downstream drop implementation could lead to an inconsistent state during unwinding that could lead to undefined behaviour.

0.9.3 has not been released to crates.io for some reason, so I suggest we add #652 and this PR to it.

@sgued sgued force-pushed the fix-unwind-vuln branch from 32f4e8d to bf4dbdb Compare April 27, 2026 19:49
@sgued sgued requested review from a team and zeenix April 27, 2026 19:50
@sgued sgued force-pushed the fix-unwind-vuln branch from bf4dbdb to 10edf9f Compare April 27, 2026 19:52
Comment thread src/vec/mod.rs Outdated
@sgued sgued force-pushed the fix-unwind-vuln branch from 10edf9f to e2465bd Compare April 28, 2026 07:26
Copy link
Copy Markdown
Contributor

@zeenix zeenix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add an explanation to the PR description (and commit message too, if we don't do a squash merge).

Comment thread src/history_buf.rs Outdated
@zeenix zeenix changed the title Fix unwind vuln Fix unwind vulnerability Apr 28, 2026
@sgued sgued force-pushed the fix-unwind-vuln branch 3 times, most recently from 23a1499 to 45bb608 Compare April 29, 2026 10:29
zeenix
zeenix previously approved these changes Apr 30, 2026
@reitermarkus
Copy link
Copy Markdown
Member

0.9.3 has not been released to crates.io for some reason, so I suggest we add #652 and this PR to it.

It is now, but anyways, the release tag already existed, and re-tagging is a very bad practice.

Comment thread src/vec/mod.rs Outdated
Comment thread src/vec/mod.rs
Comment on lines +1574 to 1583
let len = self.vec.len;
self.vec.len = LenT::ZERO;
unsafe {
// Drop all the elements that have not been moved out of vec
ptr::drop_in_place(&mut self.vec.as_mut_slice()[self.next.into_usize()..]);
// Prevent dropping of other elements
self.vec.len = LenT::ZERO;
let remaining = slice::from_raw_parts_mut(
self.vec.as_mut_ptr().add(self.next.into_usize()),
(len - self.next).into_usize(),
);
ptr::drop_in_place(remaining);
}
Copy link
Copy Markdown
Member

@reitermarkus reitermarkus Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this basically the same logic as VecInner::truncate? Does VecInner::truncate have the same vulnerability?

Copy link
Copy Markdown
Member

@reitermarkus reitermarkus Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, VecInner::truncate sets self.len before ptr::drop_in_place, so no, but would be good to clean up the unsafe block there as well to be consistent with this one, and add the same test for it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the same as truncate because we don't drop the beginning of the vec if it has already been iterated over.

Comment thread src/vec/mod.rs
fn drop(&mut self) {
let len = self.vec.len;
self.vec.len = LenT::ZERO;
unsafe {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unsafe {
// SAFETY: `self.vec` contains initialized elements in the range `self.next..len`
// which have not been consumed yet, so it is safe to create
// a mutable slice to them and drop them.
//
// `self.vec.len` is set to `0` before dropping the elements so that
// a panicking `Drop` implementation does not result in inconsistent
// state during unwinding that could lead to undefined behaviour.
unsafe {

Copy link
Copy Markdown
Contributor Author

@sgued sgued May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I added a safety comment.

@reitermarkus
Copy link
Copy Markdown
Member

Added the same test for VecInner::clear and made the implementations consistent across vec::IntoIter::drop and VecInner::truncate.

reitermarkus
reitermarkus previously approved these changes Apr 30, 2026
Comment thread CHANGELOG.md Outdated
Comment on lines +8 to +13
## [v0.9.3] 2025-04-15

- Fixed unsoundness in `Deque::clear`, `HistoryBuf::clear` and `IndexMap::clear` in the context
- Fixed unsoundness in `Deque::clear`, `HistoryBuf::clear`, `IndexMap::clear`, `Vec::IntoIter::drop` and `HistoryBuf::write` in the context
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Fixed unsoundness in `Deque::clear`, `HistoryBuf::clear`, `IndexMap::clear`, `Vec::IntoIter::drop` and `HistoryBuf::write` in the context
## [Unreleased]
- Fixed unsoundness in `Vec::IntoIter::drop` and `HistoryBuf::write` in the context of panicking drop implementations.
## [v0.9.3] 2025-04-15
- Fixed unsoundness in `Deque::clear`, `HistoryBuf::clear` and `IndexMap::clear` in the context
- Fixed unsoundness in `Deque::clear`, `HistoryBuf::clear` and `IndexMap::clear` in the context

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@reitermarkus reitermarkus force-pushed the fix-unwind-vuln branch 2 times, most recently from 1b2ac67 to d1f3f26 Compare May 1, 2026 20:40
@sgued sgued force-pushed the fix-unwind-vuln branch from d1f3f26 to 90b2d66 Compare May 4, 2026 08:01
sgued added 2 commits May 4, 2026 10:05
…ntation

Prior to this, a panic in a downstream drop implementation could lead to an inconsistent state during unwinding that could lead to undefined behaviour. For more info see rust-embedded#659
…implementation

Prior to this, a panic in a downstream drop implementation could lead to an inconsistent state during unwinding that could lead to undefined behaviour. For more info see rust-embedded#659
@sgued sgued force-pushed the fix-unwind-vuln branch from 90b2d66 to 1e59c09 Compare May 4, 2026 08:05
@sgued sgued requested a review from reitermarkus May 4, 2026 08:08
@sgued sgued force-pushed the fix-unwind-vuln branch from 1e59c09 to 5c14f2f Compare May 4, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] Panic-safety vulnerabilities in heapless v0.9.2 with demonstrated arbitrary code execution

4 participants