Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Please unblock package rust-smallvec

The insert_many function in rust-smallvec 1.6.0 and earlier suffers from a
buffer overflow if the number of items returned by the iterator is greater
than the size hint provided by the iterator. This was picked up by the rust
security team as CVE-2021-27378 and in turn by the Debian security team
who filed it with serious severity as Debian bug 985087

I did a fair bit of searching and was unable to find any code that actually
called the problem function, but nevertheless I think this is something
that should be fixed for bullseye. The new upstream version however contained
a number of feature changes that did not seem appropriate at this stage in the
release process.

Therefore I applied the upstream fix as a patch and uploaded to unstable.
The package built successfully on all release architectures and the
autopkgtests passed on all debci architectures.

unblock rust-smallvec/1.4.2-2
diff -Nru rust-smallvec-1.4.2/debian/cargo-checksum.json 
rust-smallvec-1.4.2/debian/cargo-checksum.json
--- rust-smallvec-1.4.2/debian/cargo-checksum.json      2020-10-18 
00:11:43.000000000 +0100
+++ rust-smallvec-1.4.2/debian/cargo-checksum.json      2021-03-13 
16:28:35.000000000 +0000
@@ -1 +1 @@
-{"package":"fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252","files":{}}
+{"package":"Could not get crate checksum","files":{}}
diff -Nru rust-smallvec-1.4.2/debian/changelog 
rust-smallvec-1.4.2/debian/changelog
--- rust-smallvec-1.4.2/debian/changelog        2020-10-18 00:11:43.000000000 
+0100
+++ rust-smallvec-1.4.2/debian/changelog        2021-03-13 16:28:35.000000000 
+0000
@@ -1,3 +1,12 @@
+rust-smallvec (1.4.2-2) unstable; urgency=medium
+
+  * Team upload.
+  * Package smallvec 1.4.2 from crates.io using debcargo 2.4.3
+  * Apply upstream patch to fix overflow in insert_many
+    ( Closes: 984665 )
+
+ -- Peter Michael Green <plugw...@debian.org>  Sat, 13 Mar 2021 16:28:35 +0000
+
 rust-smallvec (1.4.2-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru rust-smallvec-1.4.2/debian/copyright 
rust-smallvec-1.4.2/debian/copyright
--- rust-smallvec-1.4.2/debian/copyright        2020-10-18 00:11:43.000000000 
+0100
+++ rust-smallvec-1.4.2/debian/copyright        2021-03-13 16:28:35.000000000 
+0000
@@ -11,7 +11,7 @@
 
 Files: debian/*
 Copyright:
- 2018-2019 Debian Rust Maintainers 
<pkg-rust-maintain...@alioth-lists.debian.net>
+ 2018-2021 Debian Rust Maintainers 
<pkg-rust-maintain...@alioth-lists.debian.net>
  2018 kpcyrd <g...@rxv.cc>
  2018-2019 Wolfgang Silbermayr <wolfg...@silbermayr.at>
 License: MIT or Apache-2.0
diff -Nru rust-smallvec-1.4.2/debian/copyright.debcargo.hint 
rust-smallvec-1.4.2/debian/copyright.debcargo.hint
--- rust-smallvec-1.4.2/debian/copyright.debcargo.hint  2020-10-18 
00:11:43.000000000 +0100
+++ rust-smallvec-1.4.2/debian/copyright.debcargo.hint  2021-03-13 
16:28:35.000000000 +0000
@@ -21,9 +21,9 @@
 
 Files: debian/*
 Copyright:
- 2018-2020 Debian Rust Maintainers 
<pkg-rust-maintain...@alioth-lists.debian.net>
- 2018-2020 kpcyrd <g...@rxv.cc>
- 2018-2020 Wolfgang Silbermayr <wolfg...@silbermayr.at>
+ 2018-2021 Debian Rust Maintainers 
<pkg-rust-maintain...@alioth-lists.debian.net>
+ 2018-2021 kpcyrd <g...@rxv.cc>
+ 2018-2021 Wolfgang Silbermayr <wolfg...@silbermayr.at>
 License: MIT or Apache-2.0
 
 License: Apache-2.0
diff -Nru 
rust-smallvec-1.4.2/debian/patches/fix-insert-many-buffer-overflow.patch 
rust-smallvec-1.4.2/debian/patches/fix-insert-many-buffer-overflow.patch
--- rust-smallvec-1.4.2/debian/patches/fix-insert-many-buffer-overflow.patch    
1970-01-01 01:00:00.000000000 +0100
+++ rust-smallvec-1.4.2/debian/patches/fix-insert-many-buffer-overflow.patch    
2021-03-13 16:28:35.000000000 +0000
@@ -0,0 +1,128 @@
+Debian patch for bug 984665
+
+The patches to lib.rs and tests.rs are identical to the upstream
+commit described below. The changes to Cargo.toml (which were
+just a change of the package version number) have been excluded.
+
+commit 9998ba0694a6b51aa6604748b00b6a98f0a0039e
+Author: Matt Brubeck <mbrub...@limpet.net>
+Date:   Thu Jan 7 21:28:46 2021 -0800
+
+    Fix potential buffer overflow in `insert_many`
+    
+    Fixes #252.
+
+diff --git a/src/lib.rs b/src/lib.rs
+index 0241aefa..5e9de828 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -1009,7 +1009,7 @@ impl<A: Array> SmallVec<A> {
+     /// Insert multiple elements at position `index`, shifting all following 
elements toward the
+     /// back.
+     pub fn insert_many<I: IntoIterator<Item = A::Item>>(&mut self, index: 
usize, iterable: I) {
+-        let iter = iterable.into_iter();
++        let mut iter = iterable.into_iter();
+         if index == self.len() {
+             return self.extend(iter);
+         }
+@@ -1017,13 +1017,16 @@ impl<A: Array> SmallVec<A> {
+         let (lower_size_bound, _) = iter.size_hint();
+         assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure 
offset is indexable
+         assert!(index + lower_size_bound >= index); // Protect against 
overflow
+-        self.reserve(lower_size_bound);
++
++        let mut num_added = 0;
++        let old_len = self.len();
++        assert!(index <= old_len);
+ 
+         unsafe {
+-            let old_len = self.len();
+-            assert!(index <= old_len);
++            // Reserve space for `lower_size_bound` elements.
++            self.reserve(lower_size_bound);
+             let start = self.as_mut_ptr();
+-            let mut ptr = start.add(index);
++            let ptr = start.add(index);
+ 
+             // Move the trailing elements.
+             ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index);
+@@ -1036,42 +1039,39 @@ impl<A: Array> SmallVec<A> {
+                 len: old_len + lower_size_bound,
+             };
+ 
+-            let mut num_added = 0;
+-            for element in iter {
+-                let mut cur = ptr.add(num_added);
+-                if num_added >= lower_size_bound {
+-                    // Iterator provided more elements than the hint.  Move 
trailing items again.
+-                    self.reserve(1);
+-                    let start = self.as_mut_ptr();
+-                    ptr = start.add(index);
+-                    cur = ptr.add(num_added);
+-                    ptr::copy(cur, cur.add(1), old_len - index);
+-
+-                    guard.start = start;
+-                    guard.len += 1;
+-                    guard.skip.end += 1;
+-                }
++            while num_added < lower_size_bound {
++                let element = match iter.next() {
++                    Some(x) => x,
++                    None => break,
++                };
++                let cur = ptr.add(num_added);
+                 ptr::write(cur, element);
+                 guard.skip.start += 1;
+                 num_added += 1;
+             }
+-            mem::forget(guard);
+ 
+             if num_added < lower_size_bound {
+-                // Iterator provided fewer elements than the hint
++                // Iterator provided fewer elements than the hint. Move the 
tail backward.
+                 ptr::copy(
+                     ptr.add(lower_size_bound),
+                     ptr.add(num_added),
+                     old_len - index,
+                 );
+             }
+-
++            // There are no more duplicate or uninitialized slots, so the 
guard is not needed.
+             self.set_len(old_len + num_added);
++            mem::forget(guard);
++        }
++
++        // Insert any remaining elements one-by-one.
++        for element in iter {
++            self.insert(index + num_added, element);
++            num_added += 1;
+         }
+ 
+         struct DropOnPanic<T> {
+             start: *mut T,
+-            skip: Range<usize>,
++            skip: Range<usize>, // Space we copied-out-of, but haven't 
written-to yet.
+             len: usize,
+         }
+ 
+diff --git a/src/tests.rs b/src/tests.rs
+index 0452ae85..19f6da85 100644
+--- a/src/tests.rs
++++ b/src/tests.rs
+@@ -905,3 +905,16 @@ fn empty_macro() {
+ fn zero_size_items() {
+     SmallVec::<[(); 0]>::new().push(());
+ }
++
++#[test]
++fn test_insert_many_overflow() {
++    let mut v: SmallVec<[u8; 1]> = SmallVec::new();
++    v.push(123);
++
++    // Prepare an iterator with small lower bound
++    let iter = (0u8..5).filter(|n| n % 2 == 0);
++    assert_eq!(iter.size_hint().0, 0);
++
++    v.insert_many(0, iter);
++    assert_eq!(&*v, &[0, 2, 4, 123]);
++}
diff -Nru rust-smallvec-1.4.2/debian/patches/series 
rust-smallvec-1.4.2/debian/patches/series
--- rust-smallvec-1.4.2/debian/patches/series   1970-01-01 01:00:00.000000000 
+0100
+++ rust-smallvec-1.4.2/debian/patches/series   2021-03-13 16:28:35.000000000 
+0000
@@ -0,0 +1 @@
+fix-insert-many-buffer-overflow.patch

Reply via email to