You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The calling code might call these functions with a S: SockaddrLike larger than the number of bytes the kernel will write during the syscall. For example if a SockaddrStorage is provided to a getsockname() call for an inet socket, the syscall will write a sockaddr_in which is much smaller than the SockaddrStorage, leaving some of the SockaddrStorage bytes uninitialized. Those uninitialized bytes will then be "assumed init" by the assume_init() call, which is UB.
The simplest solution would be to use mem::MaybeUninit::<T>::zeroed() instead since I think all socket address types are POD, so zero values should be allowed. You could also instead use as_ptr() directly on the MaybeUninit without using assume_init() first, but this will give you a *const S instead of a *const sockaddr, but there's no guarantee that a *const S can be cast to a *const sockaddr.
The text was updated successfully, but these errors were encountered:
I thought that uninitialized memory would only trigger UB when the compiler could prove that the memory is uninitialized. But in this case, since the structure is initialized via the C library, that can't happen. Or to put it another way, why isn't it UB to use assume_init after libc::getsockname, even if the OS did initialize the entire structure?
There are a few places in the code that call
assume_init()
on aMaybeUninit
that may only be partially initialized, which is UB.nix/src/sys/socket/mod.rs
Lines 2217 to 2242 in 89b4976
nix/src/sys/socket/mod.rs
Lines 2340 to 2369 in 89b4976
nix/src/sys/socket/mod.rs
Lines 2045 to 2065 in 89b4976
The calling code might call these functions with a
S: SockaddrLike
larger than the number of bytes the kernel will write during the syscall. For example if aSockaddrStorage
is provided to agetsockname()
call for an inet socket, the syscall will write asockaddr_in
which is much smaller than theSockaddrStorage
, leaving some of theSockaddrStorage
bytes uninitialized. Those uninitialized bytes will then be "assumed init" by theassume_init()
call, which is UB.The simplest solution would be to use
mem::MaybeUninit::<T>::zeroed()
instead since I think all socket address types are POD, so zero values should be allowed. You could also instead useas_ptr()
directly on theMaybeUninit
without usingassume_init()
first, but this will give you a*const S
instead of a*const sockaddr
, but there's no guarantee that a*const S
can be cast to a*const sockaddr
.The text was updated successfully, but these errors were encountered: