Skip to content

Commit a01ce83

Browse files
committed
Document that writes to padding are not preserved
Document that writes to padding bytes are not preserved when an object is moved or copied. Makes progress on #1648
1 parent f998114 commit a01ce83

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

src/lib.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
//!
8585
//! # Cargo Features
8686
//!
87-
//! - **`alloc`**
87+
//! - **`alloc`**
8888
//! By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,
8989
//! the `alloc` crate is added as a dependency, and some allocation-related
9090
//! functionality is added.
@@ -94,10 +94,10 @@
9494
//! `std` crate is added as a dependency (ie, `no_std` is disabled), and
9595
//! support for some `std` types is added. `std` implies `alloc`.
9696
//!
97-
//! - **`derive`**
97+
//! - **`derive`**
9898
//! Provides derives for the core marker traits via the `zerocopy-derive`
9999
//! crate. These derives are re-exported from `zerocopy`, so it is not
100-
//! necessary to depend on `zerocopy-derive` directly.
100+
//! necessary to depend on `zerocopy-derive` directly.
101101
//!
102102
//! However, you may experience better compile times if you instead directly
103103
//! depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,
@@ -111,15 +111,15 @@
111111
//! zerocopy-derive = "0.X"
112112
//! ```
113113
//!
114-
//! - **`simd`**
114+
//! - **`simd`**
115115
//! When the `simd` feature is enabled, `FromZeros`, `FromBytes`, and
116116
//! `IntoBytes` impls are emitted for all stable SIMD types which exist on the
117117
//! target platform. Note that the layout of SIMD types is not yet stabilized,
118118
//! so these impls may be removed in the future if layout changes make them
119119
//! invalid. For more information, see the Unsafe Code Guidelines Reference
120120
//! page on the [layout of packed SIMD vectors][simd-layout].
121121
//!
122-
//! - **`simd-nightly`**
122+
//! - **`simd-nightly`**
123123
//! Enables the `simd` feature and adds support for SIMD types which are only
124124
//! available on nightly. Since these types are unstable, support for any type
125125
//! may be removed at any point in the future.
@@ -131,16 +131,16 @@
131131
//! Zerocopy is expressly designed for use in security-critical contexts. We
132132
//! strive to ensure that that zerocopy code is sound under Rust's current
133133
//! memory model, and *any future memory model*. We ensure this by:
134-
//! - **...not 'guessing' about Rust's semantics.**
134+
//! - **...not 'guessing' about Rust's semantics.**
135135
//! We annotate `unsafe` code with a precise rationale for its soundness that
136136
//! cites a relevant section of Rust's official documentation. When Rust's
137137
//! documented semantics are unclear, we work with the Rust Operational
138138
//! Semantics Team to clarify Rust's documentation.
139-
//! - **...rigorously testing our implementation.**
139+
//! - **...rigorously testing our implementation.**
140140
//! We run tests using [Miri], ensuring that zerocopy is sound across a wide
141141
//! array of supported target platforms of varying endianness and pointer
142142
//! width, and across both current and experimental memory models of Rust.
143-
//! - **...formally proving the correctness of our implementation.**
143+
//! - **...formally proving the correctness of our implementation.**
144144
//! We apply formal verification tools like [Kani][kani] to prove zerocopy's
145145
//! correctness.
146146
//!
@@ -1953,6 +1953,15 @@ fn swap<T, U>((t, u): (T, U)) -> (U, T) {
19531953
/// overhead. This is useful whenever memory is known to be in a zeroed state,
19541954
/// such memory returned from some allocation routines.
19551955
///
1956+
/// # Warning: Padding bytes
1957+
///
1958+
/// Note that, when an object is moved or copied, only the non-padding bytes of
1959+
/// that object are guaranteed to be preserved. It is unsound to assume that
1960+
/// values written to padding bytes are preserved after a move or copy. For more
1961+
/// details, see the [`FromBytes` docs][frombytes-warning-padding-bytes].
1962+
///
1963+
/// [frombytes-warning-padding-bytes]: FromBytes#warning-padding-bytes
1964+
///
19561965
/// # Implementation
19571966
///
19581967
/// **Do not implement this trait yourself!** Instead, use
@@ -2431,6 +2440,34 @@ pub use zerocopy_derive::FromBytes;
24312440
/// can be viewed as any `FromBytes` type with no runtime overhead. This is
24322441
/// useful for efficiently parsing bytes as structured data.
24332442
///
2443+
/// # Warning: Padding bytes
2444+
///
2445+
/// Note that, when an object is moved or copied, only the non-padding bytes of
2446+
/// that object are guaranteed to be preserved. It is unsound to assume that
2447+
/// values written to padding bytes are preserved after a move or copy. For
2448+
/// example, the following is unsound:
2449+
///
2450+
/// ```rust,no_run
2451+
/// use core::mem::{size_of, transmute};
2452+
/// use zerocopy::FromZeros;
2453+
/// # use zerocopy_derive::*;
2454+
///
2455+
/// // Assume `Foo` is a type with padding bytes.
2456+
/// #[derive(FromZeros, Default)]
2457+
/// struct Foo {
2458+
/// # /*
2459+
/// ...
2460+
/// # */
2461+
/// }
2462+
///
2463+
/// let mut foo: Foo = Foo::default();
2464+
/// FromZeros::zero(&mut foo);
2465+
/// // UNSOUND: Although `FromZeros::zero` writes zeros to all bytes of `foo`,
2466+
/// // those writes are not guaranteed to be preserved in padding bytes when
2467+
/// // `foo` is moved, so this may expose padding bytes as `u8`s.
2468+
/// let foo_bytes: [u8; size_of::<Foo>()] = unsafe { transmute(foo) };
2469+
/// ```
2470+
///
24342471
/// # Implementation
24352472
///
24362473
/// **Do not implement this trait yourself!** Instead, use

0 commit comments

Comments
 (0)