Move umask to a regular global variable.

The umask value is per-process, so because all POSIX open-like functions
now occur via relibc, this is valid.
This commit is contained in:
4lDO2
2024-09-25 19:39:41 +02:00
parent a736f596b9
commit 7fa5b679cc
4 changed files with 37 additions and 6 deletions
+21 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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},
};
+14 -4
View File
@@ -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<c_int, Errno> {
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 {
+1
View File
@@ -130,6 +130,7 @@ pub fn clone_default_scheme() -> Option<Box<str>> {
DEFAULT_SCHEME.lock().clone()
}
// TODO: Move to redox-rt, or maybe part of it?
pub fn open(path: &str, flags: usize) -> Result<usize> {
// TODO: SYMLOOP_MAX
const MAX_LEVEL: usize = 64;