From ed3e1c4afe7f673c179cb76c12485e95505112c8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Sep 2024 16:11:17 +0200 Subject: [PATCH] fix UB in a test also add an explicit test for the fact that a Option has padding when it is None --- tests/fail/uninit/padding-enum.rs | 2 +- tests/fail/uninit/padding-enum.stderr | 2 +- tests/fail/uninit/padding-wide-ptr.rs | 18 ++++++++++++++++++ tests/fail/uninit/padding-wide-ptr.stderr | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/fail/uninit/padding-wide-ptr.rs create mode 100644 tests/fail/uninit/padding-wide-ptr.stderr diff --git a/tests/fail/uninit/padding-enum.rs b/tests/fail/uninit/padding-enum.rs index 0ab9be2758..3852ac5c47 100644 --- a/tests/fail/uninit/padding-enum.rs +++ b/tests/fail/uninit/padding-enum.rs @@ -18,6 +18,6 @@ fn main() { unsafe { // Turns out the discriminant is (currently) stored // in the 2nd pointer, so the first half is padding. let c = &p as *const _ as *const u8; - let _val = *c.add(0); // Get the padding byte. + let _val = *c.add(0); // Get a padding byte. //~^ERROR: uninitialized } } diff --git a/tests/fail/uninit/padding-enum.stderr b/tests/fail/uninit/padding-enum.stderr index a507a5d49b..c571f18874 100644 --- a/tests/fail/uninit/padding-enum.stderr +++ b/tests/fail/uninit/padding-enum.stderr @@ -1,7 +1,7 @@ error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/padding-enum.rs:LL:CC | -LL | let _val = *c.add(0); // Get the padding byte. +LL | let _val = *c.add(0); // Get a padding byte. | ^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior diff --git a/tests/fail/uninit/padding-wide-ptr.rs b/tests/fail/uninit/padding-wide-ptr.rs new file mode 100644 index 0000000000..0403a9caba --- /dev/null +++ b/tests/fail/uninit/padding-wide-ptr.rs @@ -0,0 +1,18 @@ +use std::mem; + +// If this is `None`, the metadata becomes padding. +type T = Option<&'static str>; + +fn main() { unsafe { + let mut p: mem::MaybeUninit = mem::MaybeUninit::zeroed(); + // The copy when `T` is returned from `transmute` should destroy padding + // (even when we use `write_unaligned`, which under the hood uses an untyped copy). + p.as_mut_ptr().write_unaligned(mem::transmute((0usize, 0usize))); + // Null epresents `None`. + assert!(matches!(*p.as_ptr(), None)); + + // The second part, with the length, becomes padding. + let c = &p as *const _ as *const u8; + let _val = *c.add(mem::size_of::<*const u8>()); // Get a padding byte. + //~^ERROR: uninitialized +} } diff --git a/tests/fail/uninit/padding-wide-ptr.stderr b/tests/fail/uninit/padding-wide-ptr.stderr new file mode 100644 index 0000000000..0da72550b2 --- /dev/null +++ b/tests/fail/uninit/padding-wide-ptr.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/padding-wide-ptr.rs:LL:CC + | +LL | let _val = *c.add(mem::size_of::<*const u8>()); // Get a padding byte. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/padding-wide-ptr.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error +