-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-collectionsArea: `std::collections`Area: `std::collections`A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-criticalCritical priorityCritical priorityT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
Description
rust/library/alloc/src/vec/source_iter_marker.rs
Lines 71 to 72 in 4a20eb6
// drop any remaining values at the tail of the source | |
src.drop_remaining(); |
rust/library/alloc/src/vec/into_iter.rs
Lines 88 to 93 in 4a20eb6
pub(super) fn drop_remaining(&mut self) { | |
unsafe { | |
ptr::drop_in_place(self.as_mut_slice()); | |
} | |
self.ptr = self.end; | |
} |
SpecFromIter<T, I> for Vec<T>
calls Vec::IntoIter::drop_remaining()
. drop_remaining()
calls drop_in_place()
before overwriting the pointer. As a result, dropped elements are not invalidated and dropped again under panic.
PoC:
#![forbid(unsafe_code)]
use std::iter::FromIterator;
#[derive(Debug)]
enum MyEnum {
DroppedTwice(Box<i32>),
PanicOnDrop,
}
impl Drop for MyEnum {
fn drop(&mut self) {
match self {
MyEnum::DroppedTwice(_) => println!("Dropping!"),
MyEnum::PanicOnDrop => {
if !std::thread::panicking() {
panic!();
}
}
}
}
}
fn main() {
let v = vec![MyEnum::DroppedTwice(Box::new(123)), MyEnum::PanicOnDrop];
Vec::from_iter(v.into_iter().take(0));
}
Output:
Dropping!
thread 'main' panicked at 'explicit panic', src/main.rs:17:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Dropping!
free(): double free detected in tcache 2
Tested with rustc 1.51.0
. Here is a playground link to the code snippet.
the8472 and bukeyongscottmcm, hakivvi and wongsingfo
Metadata
Metadata
Assignees
Labels
A-collectionsArea: `std::collections`Area: `std::collections`A-destructorsArea: Destructors (`Drop`, …)Area: Destructors (`Drop`, …)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-criticalCritical priorityCritical priorityT-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.