diff --git a/rust.spec b/rust.spec index 28efbfc..10ea78b 100644 --- a/rust.spec +++ b/rust.spec @@ -53,7 +53,7 @@ Name: rust Version: 1.51.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The Rust Programming Language License: (ASL 2.0 or MIT) and (BSD and MIT) # ^ written as: (rust itself) and (bundled libraries) @@ -71,6 +71,18 @@ Source0: https://static.rust-lang.org/dist/%{rustc_package}.tar.xz # https://github.com/rust-lang/rust/issues/80810#issuecomment-781784032 Patch1: 0001-Revert-Auto-merge-of-79547.patch +# CVE-2021-28876 rust: panic safety issue in Zip implementation +# https://github.com/rust-lang/rust/pull/81741 +Patch2: rustc-1.51.0-backport-pr81741.patch + +# CVE-2021-28879 rust: integer overflow in the Zip implementation can lead to a buffer overflow +# https://github.com/rust-lang/rust/pull/82289 +Patch3: rustc-1.51.0-backport-pr82289.patch + +# CVE-2021-28878 rust: memory safety violation in Zip implementation when next_back() and next() are used together +# https://github.com/rust-lang/rust/pull/82292 +Patch4: rustc-1.51.0-backport-pr82292.patch + ### RHEL-specific patches below ### # Disable cargo->libgit2->libssh2 on RHEL, as it's not approved for FIPS (rhbz1732949) @@ -405,6 +417,9 @@ test -f '%{local_rust_root}/bin/rustc' %setup -q -n %{rustc_package} %patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %if %with disabled_libssh2 %patch100 -p1 @@ -735,6 +750,9 @@ export %{rust_env} %changelog +* Wed Apr 14 2021 Josh Stone - 1.51.0-2 +- Security fixes for CVE-2021-28876, CVE-2021-28878, CVE-2021-28879 + * Thu Mar 25 2021 Josh Stone - 1.51.0-1 - Update to 1.51.0. diff --git a/rustc-1.51.0-backport-pr81741.patch b/rustc-1.51.0-backport-pr81741.patch new file mode 100644 index 0000000..8ef22ee --- /dev/null +++ b/rustc-1.51.0-backport-pr81741.patch @@ -0,0 +1,44 @@ +From 40d3f2d7ef5835317fe9df9ecc01f4c363def4fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Thu, 4 Feb 2021 10:23:01 +0200 +Subject: [PATCH] Increment `self.index` before calling + `Iterator::self.a.__iterator_get_unchecked` in `Zip` `TrustedRandomAccess` + specialization + +Otherwise if `Iterator::self.a.__iterator_get_unchecked` panics the +index would not have been incremented yet and another call to +`Iterator::next` would read from the same index again, which is not +allowed according to the API contract of `TrustedRandomAccess` for +`!Clone`. + +Fixes https://github.com/rust-lang/rust/issues/81740 + +(cherry picked from commit 86a4b27475aab52b998c15f5758540697cc9cff0) +--- + library/core/src/iter/adapters/zip.rs | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index 98b8dca96140..9f9835345200 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -198,12 +198,13 @@ fn next(&mut self) -> Option<(A::Item, B::Item)> { + Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i))) + } + } else if A::may_have_side_effect() && self.index < self.a.size() { ++ let i = self.index; ++ self.index += 1; + // match the base implementation's potential side effects +- // SAFETY: we just checked that `self.index` < `self.a.len()` ++ // SAFETY: we just checked that `i` < `self.a.len()` + unsafe { +- self.a.__iterator_get_unchecked(self.index); ++ self.a.__iterator_get_unchecked(i); + } +- self.index += 1; + None + } else { + None +-- +2.31.1 + diff --git a/rustc-1.51.0-backport-pr82289.patch b/rustc-1.51.0-backport-pr82289.patch new file mode 100644 index 0000000..5cf5433 --- /dev/null +++ b/rustc-1.51.0-backport-pr82289.patch @@ -0,0 +1,96 @@ +From 5222e2ba2d97cd716a379b4ae6bc62c5f7c2dd36 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato +Date: Fri, 19 Feb 2021 12:15:37 +0100 +Subject: [PATCH 1/3] Increment self.len in specialized ZipImpl to avoid + underflow in size_hint + +(cherry picked from commit 66a260617a88ed1ad55a46f03c5a90d5ad3004d3) +--- + library/core/src/iter/adapters/zip.rs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index 9f9835345200..f08bfac837fe 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -200,6 +200,7 @@ fn next(&mut self) -> Option<(A::Item, B::Item)> { + } else if A::may_have_side_effect() && self.index < self.a.size() { + let i = self.index; + self.index += 1; ++ self.len += 1; + // match the base implementation's potential side effects + // SAFETY: we just checked that `i` < `self.a.len()` + unsafe { +-- +2.31.1 + + +From d39669fc8282830a374d19d204f7b4ee8eb1e381 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato +Date: Fri, 19 Feb 2021 12:16:12 +0100 +Subject: [PATCH 2/3] Add test for underflow in specialized Zip's size_hint + +(cherry picked from commit 8b9ac4d4155c74db5b317046033ab9c05a09e351) +--- + library/core/tests/iter/adapters/zip.rs | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs +index 1fce0951e365..a59771039295 100644 +--- a/library/core/tests/iter/adapters/zip.rs ++++ b/library/core/tests/iter/adapters/zip.rs +@@ -245,3 +245,23 @@ fn test_double_ended_zip() { + assert_eq!(it.next_back(), Some((3, 3))); + assert_eq!(it.next(), None); + } ++ ++#[test] ++fn test_issue_82282() { ++ fn overflowed_zip(arr: &[i32]) -> impl Iterator { ++ static UNIT_EMPTY_ARR: [(); 0] = []; ++ ++ let mapped = arr.into_iter().map(|i| *i); ++ let mut zipped = mapped.zip(UNIT_EMPTY_ARR.iter()); ++ zipped.next(); ++ zipped ++ } ++ ++ let arr = [1, 2, 3]; ++ let zip = overflowed_zip(&arr).zip(overflowed_zip(&arr)); ++ ++ assert_eq!(zip.size_hint(), (0, Some(0))); ++ for _ in zip { ++ panic!(); ++ } ++} +-- +2.31.1 + + +From 4b382167dd5ed5a6eac0cf314bfb86e3704b6e76 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato +Date: Fri, 19 Feb 2021 12:17:48 +0100 +Subject: [PATCH 3/3] Remove useless comparison since now self.index <= + self.len is an invariant + +(cherry picked from commit aeb4ea739efb70e0002a4a9c4c7b8027dd0620b3) +--- + library/core/src/iter/adapters/zip.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index f08bfac837fe..dcbcb1ce7200 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -261,7 +261,7 @@ fn next_back(&mut self) -> Option<(A::Item, B::Item)> + if sz_a != sz_b { + let sz_a = self.a.size(); + if a_side_effect && sz_a > self.len { +- for _ in 0..sz_a - cmp::max(self.len, self.index) { ++ for _ in 0..sz_a - self.len { + self.a.next_back(); + } + } +-- +2.31.1 + diff --git a/rustc-1.51.0-backport-pr82292.patch b/rustc-1.51.0-backport-pr82292.patch new file mode 100644 index 0000000..4baf72a --- /dev/null +++ b/rustc-1.51.0-backport-pr82292.patch @@ -0,0 +1,120 @@ +From 0babb88efc4d36f3defafc3c3c0343793fa05d52 Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato +Date: Wed, 3 Mar 2021 21:09:01 +0100 +Subject: [PATCH 1/2] Prevent Zip specialization from calling + __iterator_get_unchecked twice with the same index after calling next_back + +(cherry picked from commit 2371914a05f8f2763dffe6e2511d0870bcd6b461) +--- + library/core/src/iter/adapters/zip.rs | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs +index dcbcb1ce7200..7dac0c63ca2d 100644 +--- a/library/core/src/iter/adapters/zip.rs ++++ b/library/core/src/iter/adapters/zip.rs +@@ -13,9 +13,10 @@ + pub struct Zip { + a: A, + b: B, +- // index and len are only used by the specialized version of zip ++ // index, len and a_len are only used by the specialized version of zip + index: usize, + len: usize, ++ a_len: usize, + } + impl Zip { + pub(in crate::iter) fn new(a: A, b: B) -> Zip { +@@ -110,6 +111,7 @@ impl ZipImpl for Zip + b, + index: 0, // unused + len: 0, // unused ++ a_len: 0, // unused + } + } + +@@ -184,8 +186,9 @@ impl ZipImpl for Zip + B: TrustedRandomAccess + Iterator, + { + fn new(a: A, b: B) -> Self { +- let len = cmp::min(a.size(), b.size()); +- Zip { a, b, index: 0, len } ++ let a_len = a.size(); ++ let len = cmp::min(a_len, b.size()); ++ Zip { a, b, index: 0, len, a_len } + } + + #[inline] +@@ -197,7 +200,7 @@ fn next(&mut self) -> Option<(A::Item, B::Item)> { + unsafe { + Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i))) + } +- } else if A::may_have_side_effect() && self.index < self.a.size() { ++ } else if A::may_have_side_effect() && self.index < self.a_len { + let i = self.index; + self.index += 1; + self.len += 1; +@@ -264,6 +267,7 @@ fn next_back(&mut self) -> Option<(A::Item, B::Item)> + for _ in 0..sz_a - self.len { + self.a.next_back(); + } ++ self.a_len = self.len; + } + let sz_b = self.b.size(); + if b_side_effect && sz_b > self.len { +@@ -275,6 +279,7 @@ fn next_back(&mut self) -> Option<(A::Item, B::Item)> + } + if self.index < self.len { + self.len -= 1; ++ self.a_len -= 1; + let i = self.len; + // SAFETY: `i` is smaller than the previous value of `self.len`, + // which is also smaller than or equal to `self.a.len()` and `self.b.len()` +-- +2.31.1 + + +From 19af66a6f3e2bbb4780bb9eae7eb53bd13e3dd0f Mon Sep 17 00:00:00 2001 +From: Giacomo Stevanato +Date: Fri, 19 Feb 2021 15:25:09 +0100 +Subject: [PATCH 2/2] Add relevant test + +(cherry picked from commit c1bfb9a78db6d481be1d03355672712c766e20b0) +--- + library/core/tests/iter/adapters/zip.rs | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/library/core/tests/iter/adapters/zip.rs b/library/core/tests/iter/adapters/zip.rs +index a59771039295..000c15f72c88 100644 +--- a/library/core/tests/iter/adapters/zip.rs ++++ b/library/core/tests/iter/adapters/zip.rs +@@ -265,3 +265,26 @@ fn overflowed_zip(arr: &[i32]) -> impl Iterator { + panic!(); + } + } ++ ++#[test] ++fn test_issue_82291() { ++ use std::cell::Cell; ++ ++ let mut v1 = [()]; ++ let v2 = [()]; ++ ++ let called = Cell::new(0); ++ ++ let mut zip = v1 ++ .iter_mut() ++ .map(|r| { ++ called.set(called.get() + 1); ++ r ++ }) ++ .zip(&v2); ++ ++ zip.next_back(); ++ assert_eq!(called.get(), 1); ++ zip.next(); ++ assert_eq!(called.get(), 1); ++} +-- +2.31.1 +