Codebase list rust-libslirp / 7521e69
Smallvec: apply upstream patch for overflow in insert_many Peter Michael Green 3 years ago
5 changed file(s) with 142 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
0 rust-smallvec (1.4.2-2) UNRELEASED-FIXME-AUTOGENERATED-DEBCARGO; urgency=medium
1
2 * Team upload.
3 * Package smallvec 1.4.2 from crates.io using debcargo 2.4.3
4 * Apply upstream patch to fix overflow in insert_many
5 ( Closes: 984665 )
6
7 -- Peter Michael Green <plugwash@debian.org> Tue, 09 Mar 2021 15:46:51 +0000
8
09 rust-smallvec (1.4.2-1) unstable; urgency=medium
110
211 * Team upload.
1010
1111 Files: debian/*
1212 Copyright:
13 2018-2019 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
13 2018-2021 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
1414 2018 kpcyrd <git@rxv.cc>
1515 2018-2019 Wolfgang Silbermayr <wolfgang@silbermayr.at>
1616 License: MIT or Apache-2.0
2020
2121 Files: debian/*
2222 Copyright:
23 2018-2020 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
24 2018-2020 kpcyrd <git@rxv.cc>
25 2018-2020 Wolfgang Silbermayr <wolfgang@silbermayr.at>
23 2018-2021 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
24 2018-2021 kpcyrd <git@rxv.cc>
25 2018-2021 Wolfgang Silbermayr <wolfgang@silbermayr.at>
2626 License: MIT or Apache-2.0
2727
2828 License: Apache-2.0
0 Debian patch for bug 984665
1
2 The patches to lib.rs and tests.rs are identical to the upstream
3 commit described below. The changes to Cargo.toml (which were
4 just a change of the package version number) have been excluded.
5
6 commit 9998ba0694a6b51aa6604748b00b6a98f0a0039e
7 Author: Matt Brubeck <mbrubeck@limpet.net>
8 Date: Thu Jan 7 21:28:46 2021 -0800
9
10 Fix potential buffer overflow in `insert_many`
11
12 Fixes #252.
13
14 diff --git a/src/lib.rs b/src/lib.rs
15 index 0241aefa..5e9de828 100644
16 --- a/src/lib.rs
17 +++ b/src/lib.rs
18 @@ -1009,7 +1009,7 @@ impl<A: Array> SmallVec<A> {
19 /// Insert multiple elements at position `index`, shifting all following elements toward the
20 /// back.
21 pub fn insert_many<I: IntoIterator<Item = A::Item>>(&mut self, index: usize, iterable: I) {
22 - let iter = iterable.into_iter();
23 + let mut iter = iterable.into_iter();
24 if index == self.len() {
25 return self.extend(iter);
26 }
27 @@ -1017,13 +1017,16 @@ impl<A: Array> SmallVec<A> {
28 let (lower_size_bound, _) = iter.size_hint();
29 assert!(lower_size_bound <= core::isize::MAX as usize); // Ensure offset is indexable
30 assert!(index + lower_size_bound >= index); // Protect against overflow
31 - self.reserve(lower_size_bound);
32 +
33 + let mut num_added = 0;
34 + let old_len = self.len();
35 + assert!(index <= old_len);
36
37 unsafe {
38 - let old_len = self.len();
39 - assert!(index <= old_len);
40 + // Reserve space for `lower_size_bound` elements.
41 + self.reserve(lower_size_bound);
42 let start = self.as_mut_ptr();
43 - let mut ptr = start.add(index);
44 + let ptr = start.add(index);
45
46 // Move the trailing elements.
47 ptr::copy(ptr, ptr.add(lower_size_bound), old_len - index);
48 @@ -1036,42 +1039,39 @@ impl<A: Array> SmallVec<A> {
49 len: old_len + lower_size_bound,
50 };
51
52 - let mut num_added = 0;
53 - for element in iter {
54 - let mut cur = ptr.add(num_added);
55 - if num_added >= lower_size_bound {
56 - // Iterator provided more elements than the hint. Move trailing items again.
57 - self.reserve(1);
58 - let start = self.as_mut_ptr();
59 - ptr = start.add(index);
60 - cur = ptr.add(num_added);
61 - ptr::copy(cur, cur.add(1), old_len - index);
62 -
63 - guard.start = start;
64 - guard.len += 1;
65 - guard.skip.end += 1;
66 - }
67 + while num_added < lower_size_bound {
68 + let element = match iter.next() {
69 + Some(x) => x,
70 + None => break,
71 + };
72 + let cur = ptr.add(num_added);
73 ptr::write(cur, element);
74 guard.skip.start += 1;
75 num_added += 1;
76 }
77 - mem::forget(guard);
78
79 if num_added < lower_size_bound {
80 - // Iterator provided fewer elements than the hint
81 + // Iterator provided fewer elements than the hint. Move the tail backward.
82 ptr::copy(
83 ptr.add(lower_size_bound),
84 ptr.add(num_added),
85 old_len - index,
86 );
87 }
88 -
89 + // There are no more duplicate or uninitialized slots, so the guard is not needed.
90 self.set_len(old_len + num_added);
91 + mem::forget(guard);
92 + }
93 +
94 + // Insert any remaining elements one-by-one.
95 + for element in iter {
96 + self.insert(index + num_added, element);
97 + num_added += 1;
98 }
99
100 struct DropOnPanic<T> {
101 start: *mut T,
102 - skip: Range<usize>,
103 + skip: Range<usize>, // Space we copied-out-of, but haven't written-to yet.
104 len: usize,
105 }
106
107 diff --git a/src/tests.rs b/src/tests.rs
108 index 0452ae85..19f6da85 100644
109 --- a/src/tests.rs
110 +++ b/src/tests.rs
111 @@ -905,3 +905,16 @@ fn empty_macro() {
112 fn zero_size_items() {
113 SmallVec::<[(); 0]>::new().push(());
114 }
115 +
116 +#[test]
117 +fn test_insert_many_overflow() {
118 + let mut v: SmallVec<[u8; 1]> = SmallVec::new();
119 + v.push(123);
120 +
121 + // Prepare an iterator with small lower bound
122 + let iter = (0u8..5).filter(|n| n % 2 == 0);
123 + assert_eq!(iter.size_hint().0, 0);
124 +
125 + v.insert_many(0, iter);
126 + assert_eq!(&*v, &[0, 2, 4, 123]);
127 +}
0 fix-insert-many-buffer-overflow.patch