Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid mem::uninitialized() in std::sys::unix #62163

Merged
merged 2 commits into from
Jun 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/libstd/sys/unix/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ impl Condvar {
target_os = "android",
target_os = "hermit")))]
pub unsafe fn init(&mut self) {
use crate::mem;
let mut attr: libc::pthread_condattr_t = mem::uninitialized();
let r = libc::pthread_condattr_init(&mut attr);
use crate::mem::MaybeUninit;
let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
let r = libc::pthread_condattr_init(attr.as_mut_ptr());
assert_eq!(r, 0);
let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
assert_eq!(r, 0);
let r = libc::pthread_cond_init(self.inner.get(), &attr);
let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
assert_eq!(r, 0);
let r = libc::pthread_condattr_destroy(&mut attr);
let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
assert_eq!(r, 0);
}

Expand Down
11 changes: 5 additions & 6 deletions src/libstd/sys/unix/ext/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL;
target_os = "haiku")))]
const MSG_NOSIGNAL: libc::c_int = 0x0;

fn sun_path_offset() -> usize {
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
// Work with an actual instance of the type since using a null pointer is UB
let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
let base = &addr as *const _ as usize;
let base = addr as *const _ as usize;
let path = &addr.sun_path as *const _ as usize;
path - base
}
Expand All @@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl
// null byte for pathname addresses is already there because we zeroed the
// struct

let mut len = sun_path_offset() + bytes.len();
let mut len = sun_path_offset(&addr) + bytes.len();
match bytes.get(0) {
Some(&0) | None => {}
Some(_) => len += 1,
Expand Down Expand Up @@ -122,7 +121,7 @@ impl SocketAddr {
if len == 0 {
// When there is a datagram from unnamed unix socket
// linux returns zero bytes of address
len = sun_path_offset() as libc::socklen_t; // i.e., zero-length address
len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
} else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
return Err(io::Error::new(io::ErrorKind::InvalidInput,
"file descriptor did not correspond to a Unix socket"));
Expand Down Expand Up @@ -200,7 +199,7 @@ impl SocketAddr {
}

fn address<'a>(&'a self) -> AddressKind<'a> {
let len = self.len as usize - sun_path_offset();
let len = self.len as usize - sun_path_offset(&self.addr);
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };

// macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
Expand Down
24 changes: 12 additions & 12 deletions src/libstd/sys/unix/mutex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cell::UnsafeCell;
use crate::mem;
use crate::mem::MaybeUninit;

pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }

Expand Down Expand Up @@ -40,14 +40,14 @@ impl Mutex {
// references, we instead create the mutex with type
// PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
// re-lock it from the same thread, thus avoiding undefined behavior.
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
let r = libc::pthread_mutexattr_init(&mut attr);
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
debug_assert_eq!(r, 0);
let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
debug_assert_eq!(r, 0);
let r = libc::pthread_mutex_init(self.inner.get(), &attr);
let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
debug_assert_eq!(r, 0);
let r = libc::pthread_mutexattr_destroy(&mut attr);
let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
debug_assert_eq!(r, 0);
}
#[inline]
Expand Down Expand Up @@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {}

impl ReentrantMutex {
pub unsafe fn uninitialized() -> ReentrantMutex {
ReentrantMutex { inner: mem::uninitialized() }
ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
}

pub unsafe fn init(&mut self) {
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
debug_assert_eq!(result, 0);
let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
libc::PTHREAD_MUTEX_RECURSIVE);
debug_assert_eq!(result, 0);
let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
debug_assert_eq!(result, 0);
let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
debug_assert_eq!(result, 0);
}

Expand Down
14 changes: 7 additions & 7 deletions src/libstd/sys/unix/process/process_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ mod tests {

#[cfg(target_os = "android")]
unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
set.write_bytes(0u8, 1);
return 0;
}

Expand Down Expand Up @@ -466,11 +466,11 @@ mod tests {
// Test to make sure that a signal mask does not get inherited.
let mut cmd = Command::new(OsStr::new("cat"));

let mut set: libc::sigset_t = mem::uninitialized();
let mut old_set: libc::sigset_t = mem::uninitialized();
t!(cvt(sigemptyset(&mut set)));
t!(cvt(sigaddset(&mut set, libc::SIGINT)));
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
t!(cvt(sigemptyset(set.as_mut_ptr())));
t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));

cmd.stdin(Stdio::MakePipe);
cmd.stdout(Stdio::MakePipe);
Expand All @@ -479,7 +479,7 @@ mod tests {
let stdin_write = pipes.stdin.take().unwrap();
let stdout_read = pipes.stdout.take().unwrap();

t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
ptr::null_mut())));

t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
Expand Down
58 changes: 28 additions & 30 deletions src/libstd/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,26 +202,24 @@ impl Command {
// emscripten has no signal support.
#[cfg(not(any(target_os = "emscripten")))]
{
use crate::mem;
use crate::mem::MaybeUninit;
// Reset signal handling so the child process starts in a
// standardized state. libstd ignores SIGPIPE, and signal-handling
// libraries often set a mask. Child processes inherit ignored
// signals and the signal mask from their parent, but most
// UNIX programs do not reset these things on their own, so we
// need to clean things up now to avoid confusing the program
// we're about to run.
let mut set: libc::sigset_t = mem::uninitialized();
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
if cfg!(target_os = "android") {
// Implementing sigemptyset allow us to support older Android
// versions. See the comment about Android and sig* functions in
// process_common.rs
libc::memset(&mut set as *mut _ as *mut _,
0,
mem::size_of::<libc::sigset_t>());
set.as_mut_ptr().write_bytes(0u8, 1);
RalfJung marked this conversation as resolved.
Show resolved Hide resolved
} else {
cvt(libc::sigemptyset(&mut set))?;
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
}
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
ptr::null_mut()))?;
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
if ret == libc::SIG_ERR {
Expand Down Expand Up @@ -273,7 +271,7 @@ impl Command {
fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
-> io::Result<Option<Process>>
{
use crate::mem;
use crate::mem::MaybeUninit;
use crate::sys;

if self.get_gid().is_some() ||
Expand Down Expand Up @@ -315,63 +313,63 @@ impl Command {

let mut p = Process { pid: 0, status: None };

struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>);

impl Drop for PosixSpawnFileActions {
fn drop(&mut self) {
unsafe {
libc::posix_spawn_file_actions_destroy(&mut self.0);
libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
}
}
}

struct PosixSpawnattr(libc::posix_spawnattr_t);
struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>);

impl Drop for PosixSpawnattr {
fn drop(&mut self) {
unsafe {
libc::posix_spawnattr_destroy(&mut self.0);
libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
}
}
}

unsafe {
let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
let mut attrs = PosixSpawnattr(mem::uninitialized());
let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
let mut attrs = PosixSpawnattr(MaybeUninit::uninit());

libc::posix_spawnattr_init(&mut attrs.0);
libc::posix_spawn_file_actions_init(&mut file_actions.0);
libc::posix_spawnattr_init(attrs.0.as_mut_ptr());
libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());

if let Some(fd) = stdio.stdin.fd() {
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
fd,
libc::STDIN_FILENO))?;
}
if let Some(fd) = stdio.stdout.fd() {
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
fd,
libc::STDOUT_FILENO))?;
}
if let Some(fd) = stdio.stderr.fd() {
cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
fd,
libc::STDERR_FILENO))?;
}
if let Some((f, cwd)) = addchdir {
cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
}

let mut set: libc::sigset_t = mem::uninitialized();
cvt(libc::sigemptyset(&mut set))?;
cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
&set))?;
cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
&set))?;
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
cvt(libc::sigemptyset(set.as_mut_ptr()))?;
cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
set.as_ptr()))?;
cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
set.as_ptr()))?;

let flags = libc::POSIX_SPAWN_SETSIGDEF |
libc::POSIX_SPAWN_SETSIGMASK;
cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;

// Make sure we synchronize access to the global `environ` resource
let _env_lock = sys::os::env_lock();
Expand All @@ -380,8 +378,8 @@ impl Command {
let ret = libc::posix_spawnp(
&mut p.pid,
self.get_argv()[0],
&file_actions.0,
&attrs.0,
file_actions.0.as_ptr(),
attrs.0.as_ptr(),
self.get_argv().as_ptr() as *const _,
envp as *const _,
);
Expand Down