summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/rust/files/1.51.0-CVE-2021-31162.patch')
-rw-r--r--dev-lang/rust/files/1.51.0-CVE-2021-31162.patch195
1 files changed, 195 insertions, 0 deletions
diff --git a/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch b/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch
new file mode 100644
index 000000000000..fd9165ea3c5e
--- /dev/null
+++ b/dev-lang/rust/files/1.51.0-CVE-2021-31162.patch
@@ -0,0 +1,195 @@
+From fa89c0fbcfa8f4d44f153b1195ec5a305540ffc4 Mon Sep 17 00:00:00 2001
+From: The8472 <git@infinite-source.de>
+Date: Mon, 29 Mar 2021 04:22:34 +0200
+Subject: [PATCH 1/3] add testcase for double-drop during Vec in-place
+ collection
+
+---
+ library/alloc/tests/vec.rs | 38 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
+index c142536cd2dfb..b926c697d58ab 100644
+--- a/library/alloc/tests/vec.rs
++++ b/library/alloc/tests/vec.rs
+@@ -1027,7 +1027,7 @@ fn test_from_iter_specialization_head_tail_drop() {
+ }
+
+ #[test]
+-fn test_from_iter_specialization_panic_drop() {
++fn test_from_iter_specialization_panic_during_iteration_drops() {
+ let drop_count: Vec<_> = (0..=2).map(|_| Rc::new(())).collect();
+ let src: Vec<_> = drop_count.iter().cloned().collect();
+ let iter = src.into_iter();
+@@ -1050,6 +1050,42 @@ fn test_from_iter_specialization_panic_drop() {
+ );
+ }
+
++#[test]
++fn test_from_iter_specialization_panic_during_drop_leaks() {
++ static mut DROP_COUNTER: usize = 0;
++
++ #[derive(Debug)]
++ enum Droppable {
++ DroppedTwice(Box<i32>),
++ PanicOnDrop,
++ }
++
++ impl Drop for Droppable {
++ fn drop(&mut self) {
++ match self {
++ Droppable::DroppedTwice(_) => {
++ unsafe {
++ DROP_COUNTER += 1;
++ }
++ println!("Dropping!")
++ }
++ Droppable::PanicOnDrop => {
++ if !std::thread::panicking() {
++ panic!();
++ }
++ }
++ }
++ }
++ }
++
++ let _ = std::panic::catch_unwind(AssertUnwindSafe(|| {
++ let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop];
++ let _ = v.into_iter().take(0).collect::<Vec<_>>();
++ }));
++
++ assert_eq!(unsafe { DROP_COUNTER }, 1);
++}
++
+ #[test]
+ fn test_cow_from() {
+ let borrowed: &[_] = &["borrowed", "(slice)"];
+
+From 421f5d282a51e130d3ca7c4524d8ad6753437da9 Mon Sep 17 00:00:00 2001
+From: The8472 <git@infinite-source.de>
+Date: Mon, 29 Mar 2021 04:22:48 +0200
+Subject: [PATCH 2/3] fix double-drop in in-place collect specialization
+
+---
+ library/alloc/src/vec/into_iter.rs | 27 ++++++++++++++-------
+ library/alloc/src/vec/source_iter_marker.rs | 4 +--
+ 2 files changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
+index bcbdffabc7fbe..324e894bafd23 100644
+--- a/library/alloc/src/vec/into_iter.rs
++++ b/library/alloc/src/vec/into_iter.rs
+@@ -85,20 +85,29 @@ impl<T, A: Allocator> IntoIter<T, A> {
+ ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len())
+ }
+
+- pub(super) fn drop_remaining(&mut self) {
+- unsafe {
+- ptr::drop_in_place(self.as_mut_slice());
+- }
+- self.ptr = self.end;
+- }
++ /// Drops remaining elements and relinquishes the backing allocation.
++ ///
++ /// This is roughly equivalent to the following, but more efficient
++ ///
++ /// ```
++ /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
++ /// (&mut into_iter).for_each(core::mem::drop);
++ /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); }
++ /// ```
++ pub(super) fn forget_allocation_drop_remaining(&mut self) {
++ let remaining = self.as_raw_mut_slice();
+
+- /// Relinquishes the backing allocation, equivalent to
+- /// `ptr::write(&mut self, Vec::new().into_iter())`
+- pub(super) fn forget_allocation(&mut self) {
++ // overwrite the individual fields instead of creating a new
++ // struct and then overwriting &mut self.
++ // this creates less assembly
+ self.cap = 0;
+ self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
+ self.ptr = self.buf.as_ptr();
+ self.end = self.buf.as_ptr();
++
++ unsafe {
++ ptr::drop_in_place(remaining);
++ }
+ }
+ }
+
+diff --git a/library/alloc/src/vec/source_iter_marker.rs b/library/alloc/src/vec/source_iter_marker.rs
+index 50882fc17673e..e857d284d3ab6 100644
+--- a/library/alloc/src/vec/source_iter_marker.rs
++++ b/library/alloc/src/vec/source_iter_marker.rs
+@@ -69,9 +69,9 @@ where
+ }
+
+ // drop any remaining values at the tail of the source
+- src.drop_remaining();
+ // but prevent drop of the allocation itself once IntoIter goes out of scope
+- src.forget_allocation();
++ // if the drop panics then we also leak any elements collected into dst_buf
++ src.forget_allocation_drop_remaining();
+
+ let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) };
+
+
+From 328a5e040780984c60dde2db300dad4f1323c39d Mon Sep 17 00:00:00 2001
+From: The8472 <git@infinite-source.de>
+Date: Fri, 2 Apr 2021 23:06:05 +0200
+Subject: [PATCH 3/3] cleanup leak after test to make miri happy
+
+---
+ library/alloc/tests/vec.rs | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
+index b926c697d58ab..b9fe07c73e55e 100644
+--- a/library/alloc/tests/vec.rs
++++ b/library/alloc/tests/vec.rs
+@@ -1,3 +1,4 @@
++use alloc::boxed::Box;
+ use std::borrow::Cow;
+ use std::cell::Cell;
+ use std::collections::TryReserveError::*;
+@@ -1056,14 +1057,14 @@ fn test_from_iter_specialization_panic_during_drop_leaks() {
+
+ #[derive(Debug)]
+ enum Droppable {
+- DroppedTwice(Box<i32>),
++ DroppedTwice,
+ PanicOnDrop,
+ }
+
+ impl Drop for Droppable {
+ fn drop(&mut self) {
+ match self {
+- Droppable::DroppedTwice(_) => {
++ Droppable::DroppedTwice => {
+ unsafe {
+ DROP_COUNTER += 1;
+ }
+@@ -1078,12 +1079,21 @@ fn test_from_iter_specialization_panic_during_drop_leaks() {
+ }
+ }
+
++ let mut to_free: *mut Droppable = core::ptr::null_mut();
++ let mut cap = 0;
++
+ let _ = std::panic::catch_unwind(AssertUnwindSafe(|| {
+- let v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop];
++ let mut v = vec![Droppable::DroppedTwice, Droppable::PanicOnDrop];
++ to_free = v.as_mut_ptr();
++ cap = v.capacity();
+ let _ = v.into_iter().take(0).collect::<Vec<_>>();
+ }));
+
+ assert_eq!(unsafe { DROP_COUNTER }, 1);
++ // clean up the leak to keep miri happy
++ unsafe {
++ Vec::from_raw_parts(to_free, 0, cap);
++ }
+ }
+
+ #[test]