Skip to content

Commit f70e422

Browse files
authored
[pointer] Ptr::iter takes self by value (#3421)
This fixes a prior soundness hole - `Ptr::iter` took `&self`, permitting multiple overlapping `Exclusive` `Ptr`s to be created at the same time. In CI, when running `cargo-semver-checks`, don't pass `--cfg zerocopy_unstable_ptr`, as we don't want to semver-check unstable APIs. Release 0.8.50. Fixes #3419 gherrit-pr-id: Ibb7d512d9e12ecfd118bb018bcae10d17279c2ed
1 parent 5fc5d5b commit f70e422

5 files changed

Lines changed: 38 additions & 10 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,10 @@ jobs:
640640
# SIMD type impls), and so we need to run on each target.
641641
- name: Check semver compatibility
642642
uses: obi1kenobi/cargo-semver-checks-action@6b69fcf40e9b5fb17adeb57e4b6ecd020649a239 # v2.9
643+
env:
644+
# `zerocopy_unstable_ptr` exposes unstable API, so it should not be
645+
# included in semver checks.
646+
RUSTDOCFLAGS: -Dwarnings
643647
with:
644648
# Don't semver check zerocopy-derive; as a proc macro, it doesn't have
645649
# an API that cargo-semver-checks can understand.

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
[package]
1616
edition = "2021"
1717
name = "zerocopy"
18-
version = "0.8.49"
18+
version = "0.8.50"
1919
authors = [
2020
"Joshua Liebow-Feeser <joshlf@google.com>",
2121
"Jack Wrenn <jswrenn@amazon.com>",
@@ -124,13 +124,13 @@ __internal_use_only_features_that_work_on_stable = [
124124
]
125125

126126
[dependencies]
127-
zerocopy-derive = { version = "=0.8.49", path = "zerocopy-derive", optional = true }
127+
zerocopy-derive = { version = "=0.8.50", path = "zerocopy-derive", optional = true }
128128

129129
# The "associated proc macro pattern" ensures that the versions of zerocopy and
130130
# zerocopy-derive remain equal, even if the 'derive' feature isn't used.
131131
# See: https://github.com/matklad/macro-dep-test
132132
[target.'cfg(any())'.dependencies]
133-
zerocopy-derive = { version = "=0.8.49", path = "zerocopy-derive" }
133+
zerocopy-derive = { version = "=0.8.50", path = "zerocopy-derive" }
134134

135135
[dev-dependencies]
136136
# FIXME(#381) Remove this dependency once we have our own layout gadgets.
@@ -142,4 +142,4 @@ rustversion = "1.0"
142142
static_assertions = "1.1"
143143
testutil = { path = "testutil" }
144144
# In tests, unlike in production, zerocopy-derive is not optional
145-
zerocopy-derive = { version = "=0.8.49", path = "zerocopy-derive" }
145+
zerocopy-derive = { version = "=0.8.50", path = "zerocopy-derive" }

src/pointer/ptr.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,10 +1268,17 @@ mod _project {
12681268
{
12691269
/// Iteratively projects the elements `Ptr<T>` from `Ptr<[T]>`.
12701270
#[inline]
1271-
pub fn iter(&self) -> impl Iterator<Item = Ptr<'a, T, I>> {
1271+
pub fn iter(self) -> impl Iterator<Item = Ptr<'a, T, I>> {
12721272
// SAFETY:
1273-
// 0. `elem` conforms to the aliasing invariant of `I::Aliasing`
1274-
// because projection does not impact the aliasing invariant.
1273+
// 0. `elem` conforms to the aliasing invariant of `I::Aliasing`:
1274+
// - `Exclusive`: `self` is consumed by value, and therefore
1275+
// cannot be used to access the slice while any yielded
1276+
// element `Ptr` is live. Each non-zero-sized element is a
1277+
// disjoint byte range within the slice, and zero-sized
1278+
// elements address no bytes, so distinct yielded element
1279+
// `Ptr`s do not alias each other.
1280+
// - `Shared`: It is sound for multiple shared `Ptr`s to exist
1281+
// simultaneously which reference the same memory.
12751282
// 1. `elem`, conditionally, conforms to the validity invariant of
12761283
// `I::Alignment`. If `elem` is projected from data well-aligned
12771284
// for `[T]`, `elem` will be valid for `T`.
@@ -1557,4 +1564,21 @@ mod tests {
15571564
Err(e) => panic!("wrong error type: {:?}", e),
15581565
}
15591566
}
1567+
1568+
#[test]
1569+
fn test_iter_exclusive_yields_disjoint_ptrs() {
1570+
let mut arr = [0u8, 1, 2, 3];
1571+
1572+
{
1573+
let mut iter = Ptr::from_mut(&mut arr[..]).iter();
1574+
let first = iter.next().unwrap().as_mut();
1575+
let second = iter.next().unwrap().as_mut();
1576+
1577+
*first = 10;
1578+
*second = 20;
1579+
*first = 30;
1580+
}
1581+
1582+
assert_eq!(arr, [30, 20, 2, 3]);
1583+
}
15601584
}

zerocopy-derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[package]
1010
edition = "2021"
1111
name = "zerocopy-derive"
12-
version = "0.8.49"
12+
version = "0.8.50"
1313
authors = ["Joshua Liebow-Feeser <joshlf@google.com>", "Jack Wrenn <jswrenn@amazon.com>"]
1414
description = "Custom derive for traits from the zerocopy crate"
1515
license = "BSD-2-Clause OR Apache-2.0 OR MIT"

0 commit comments

Comments
 (0)