-
Notifications
You must be signed in to change notification settings - Fork 549
Open
Description
Note: Uninitialized memory is also implicitly invalid for any type that has a restricted set of valid values. In other words, the only cases in which reading uninitialized memory is permitted are inside unions and in “padding” (the gaps between the fields of a type).
miri rejects reading from the unitialized part of a union:
use std::mem::MaybeUninit;
union U {
_f1: f32,
_f2: (),
}
fn main() {
let u: U = unsafe { MaybeUninit::uninit().assume_init() };
eprintln!("{:?}", unsafe { u._f1 });
}
error: Undefined Behavior: reading memory at alloc165[0x0..0x4], but memory is uninitialized at [0x0..0x4], and this operation requires initialized memory
--> src/main.rs:10:32
|
10 | eprintln!("{:?}", unsafe { u._f1 });
| ^^^^^ Undefined Behavior occurred here
|
= 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 src/main.rs:10:32: 10:37
Uninitialized memory occurred at alloc165[0x0..0x4], in this allocation:
alloc165 (stack variable, size: 4, align: 4) {
__ __ __ __ │ ░░░░
}
And it also rejects reading from uninitialized padding bytes:
#[repr(C)]
struct S {
a: u16,
b: u32,
}
fn main() {
let s = S {
a: u16::MAX,
b: u32::MAX,
};
let byte_slice = unsafe {
std::slice::from_raw_parts((&s as *const S) as *const u8, std::mem::size_of::<S>())
};
eprintln!("{:x?}", byte_slice);
}
ff, ff, error: Undefined Behavior: reading memory at alloc165[0x2..0x3], but memory is uninitialized at [0x2..0x3], and this operation requires initialized memory
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/num.rs:73:1
|
73 | radix_integers! { i8, u8 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= 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`
--> src/main.rs:15:5
|
15 | eprintln!("{:x?}", byte_slice);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `radix_integer` which comes from the expansion of the macro `eprintln` (in Nightly builds, run with -Z macro-backtrace for more info)
Uninitialized memory occurred at alloc165[0x2..0x3], in this allocation:
alloc165 (stack variable, size: 8, align: 4) {
ff ff __ __ ff ff ff ff │ ..░░....
}
Miri's behavior is consistent with this discussion in UCG: rust-lang/unsafe-code-guidelines#395
And consistent with the glossary, afaict: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/glossary.md#padding
Should the reference be updated? I possibly misunderstood the paragraph, in which case it should probably be updated anyway.
Metadata
Metadata
Assignees
Labels
No labels