diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index 45779f6b89..2f9bd82c30 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -1,4 +1,7 @@ -use core::ptr::addr_of; +use core::{ + ptr::addr_of, + sync::atomic::{AtomicU32, Ordering}, +}; use syscall::{ error::{Error, Result, EINTR}, @@ -114,3 +117,20 @@ pub fn posix_kill_thread(thread_fd: usize, signal: u32) -> Result<()> { Err(error) => Err(error), } } + +static UMASK: AtomicU32 = AtomicU32::new(0o022); + +/// Controls the set of bits removed from the `mode` mask when new file descriptors are created. +/// +/// Must be validated by the caller +// +// TODO: validate here? +#[inline] +pub fn swap_umask(mask: u32) -> u32 { + UMASK.swap(mask, Ordering::AcqRel) +} + +#[inline] +pub fn get_umask() -> u32 { + UMASK.load(Ordering::Acquire) +} diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index a8785a8807..61e1780f5b 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -5,8 +5,8 @@ use core::{mem, ptr}; use cbitset::BitSet; use crate::{ - error::{Errno, ResultExt}, c_str::CStr, + error::{Errno, ResultExt}, header::{errno, time::timespec}, platform::{self, types::*, Pal, PalSignal, Sys}, }; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 57482b4d9b..62e90f61cb 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -8,7 +8,7 @@ use syscall::{ self, data::{Map, Stat as redox_stat, StatVfs as redox_statvfs, TimeSpec as redox_timespec}, dirent::{DirentHeader, DirentKind}, - Error, PtraceEvent, Result, EMFILE, + Error, PtraceEvent, Result, EMFILE, MODE_PERM, }; use crate::{ @@ -25,7 +25,7 @@ use crate::{ sys_mman::{MAP_ANONYMOUS, MAP_FAILED, PROT_READ, PROT_WRITE}, sys_random, sys_resource::{rlimit, rusage, RLIM_INFINITY}, - sys_stat::{stat, S_ISGID, S_ISUID}, + sys_stat::{stat, S_ISGID, S_ISUID, S_ISVTX}, sys_statvfs::statvfs, sys_time::{timeval, timezone}, sys_utsname::{utsname, UTSLENGTH}, @@ -784,7 +784,16 @@ impl Pal for Sys { fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result { let path = path.to_str().map_err(|_| Errno(EINVAL))?; - Ok(libredox::open(path, oflag, mode)? as c_int) + // POSIX states that umask should affect the following: + // + // open, openat (TODO), creat, mkdir, mkdirat (TODO), + // mkfifo, mkfifoat (TODO), mknod, mknodat (TODO), + // mq_open, and sem_open, + // + // all of which (the ones that exist thus far) currently call this function. + let effective_mode = mode & !(redox_rt::sys::get_umask() as mode_t); + + Ok(libredox::open(path, oflag, effective_mode)? as c_int) } fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int { @@ -966,7 +975,8 @@ impl Pal for Sys { } fn umask(mask: mode_t) -> mode_t { - e(syscall::umask(mask as usize)) as mode_t + let new_effective_mask = mask & mode_t::from(MODE_PERM) & !S_ISVTX; + (redox_rt::sys::swap_umask(new_effective_mask as u32) as mode_t) & !S_ISVTX } fn uname(utsname: *mut utsname) -> c_int { diff --git a/src/platform/redox/path.rs b/src/platform/redox/path.rs index 414056a63c..9d6739a463 100644 --- a/src/platform/redox/path.rs +++ b/src/platform/redox/path.rs @@ -130,6 +130,7 @@ pub fn clone_default_scheme() -> Option> { DEFAULT_SCHEME.lock().clone() } +// TODO: Move to redox-rt, or maybe part of it? pub fn open(path: &str, flags: usize) -> Result { // TODO: SYMLOOP_MAX const MAX_LEVEL: usize = 64;