-
Notifications
You must be signed in to change notification settings - Fork 738
Description
This is similar to what is reported in #2693, but more general.
- :
Lines 111 to 121 in ba63e90
let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit(); unsafe { let p = attr.as_mut_ptr(); (*p).mq_flags = mq_flags; (*p).mq_maxmsg = mq_maxmsg; (*p).mq_msgsize = mq_msgsize; (*p).mq_curmsgs = mq_curmsgs; MqAttr { mq_attr: attr.assume_init(), } } mq_attrhas a private field so the struct cannot possibly be initialized. - https://github.com/nix-rust/nix/blob/ba63e90362e24dcebbf96783da668647ceace21c/src/sys/signalfd.rs#L115C51-L127:
signalfd_siginfohas padding fields - and other places in that file:
Lines 25 to 31 in ba63e90
let mut attr = mem::MaybeUninit::uninit(); let res = unsafe { libc::posix_spawnattr_init(attr.as_mut_ptr()) }; Errno::result(res)?; let attr = unsafe { attr.assume_init() }; Ok(PosixSpawnAttr { attr }) posix_spawnattr_thas padding fields - : the contents of
Line 33 in ba63e90
let mut fdset = mem::MaybeUninit::uninit(); fdsetare not public API and may contain padding fields - : stat contains padding
Line 215 in ba63e90
let mut dst = mem::MaybeUninit::uninit();
The first example is the most problematic, that UB caused a (fairly innocuous) issue in Fedora's CI rust-lang/libc#4892 (comment). This happened to be fixed in the latest libc, but that was due to a change in internal details that shouldn't be relied upon.
In general, it's really not ever robust to use MaybeUninit::uninit with libc types if .assume_init() will be called. For anything that has padding fields now or may add fields in the future, it's easy to wind up in a situation where a system libc/kernel is only partially initializing the type and assume_init creates UB. I doubt the cost of zeroing will be noticeable when there is usually a syscall overhead.
(It's fine to leave the type wrapped in MaybeUninit and only access useful fields via raw pointers, same as in C, but that's not ergonomic.)