Add support for umask
This commit is contained in:
parent
05d4c7d7db
commit
87c1c9a8b3
2
deps/sefs
vendored
2
deps/sefs
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 41484829326a6bcbd92343f7c1bdcf4acf5a56f4
|
Subproject commit 8d999ffdf066cc0601c5a726ccfcca75437ced0b
|
@ -53,6 +53,17 @@ impl FileMode {
|
|||||||
pub fn has_set_gid(&self) -> bool {
|
pub fn has_set_gid(&self) -> bool {
|
||||||
self.contains(FileMode::S_ISGID)
|
self.contains(FileMode::S_ISGID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Umask is FileMode & 0o777, only the file permission bits are used
|
||||||
|
pub fn to_umask(mut self) -> Self {
|
||||||
|
self.remove(Self::S_ISUID | Self::S_ISGID | Self::S_ISVTX);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default umask is 0o022
|
||||||
|
pub fn default_umask() -> Self {
|
||||||
|
Self::S_IWGRP | Self::S_IWOTH
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_fchmodat(fs_path: &FsPath, mode: FileMode) -> Result<()> {
|
pub fn do_fchmodat(fs_path: &FsPath, mode: FileMode) -> Result<()> {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn do_mkdirat(fs_path: &FsPath, mode: usize) -> Result<()> {
|
pub fn do_mkdirat(fs_path: &FsPath, mode: FileMode) -> Result<()> {
|
||||||
debug!("mkdirat: fs_path: {:?}, mode: {:#o}", fs_path, mode);
|
debug!("mkdirat: fs_path: {:?}, mode: {:#o}", fs_path, mode.bits());
|
||||||
|
|
||||||
let path = fs_path.to_abs_path()?;
|
let path = fs_path.to_abs_path()?;
|
||||||
let (dir_path, file_name) = split_path(&path);
|
let (dir_path, file_name) = split_path(&path);
|
||||||
|
let current = current!();
|
||||||
let inode = {
|
let inode = {
|
||||||
let current = current!();
|
|
||||||
let fs = current.fs().read().unwrap();
|
let fs = current.fs().read().unwrap();
|
||||||
fs.lookup_inode(dir_path)?
|
fs.lookup_inode(dir_path)?
|
||||||
};
|
};
|
||||||
@ -16,6 +16,7 @@ pub fn do_mkdirat(fs_path: &FsPath, mode: usize) -> Result<()> {
|
|||||||
if !inode.allow_write()? {
|
if !inode.allow_write()? {
|
||||||
return_errno!(EPERM, "dir cannot be written");
|
return_errno!(EPERM, "dir cannot be written");
|
||||||
}
|
}
|
||||||
inode.create(file_name, FileType::Dir, mode as u32)?;
|
let masked_mode = mode & !current.process().umask();
|
||||||
|
inode.create(file_name, FileType::Dir, masked_mode.bits())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn do_openat(fs_path: &FsPath, flags: u32, mode: u32) -> Result<FileDesc> {
|
pub fn do_openat(fs_path: &FsPath, flags: u32, mode: FileMode) -> Result<FileDesc> {
|
||||||
debug!(
|
debug!(
|
||||||
"openat: fs_path: {:?}, flags: {:#o}, mode: {:#o}",
|
"openat: fs_path: {:?}, flags: {:#o}, mode: {:#o}",
|
||||||
fs_path, flags, mode
|
fs_path,
|
||||||
|
flags,
|
||||||
|
mode.bits()
|
||||||
);
|
);
|
||||||
|
|
||||||
let path = fs_path.to_abs_path()?;
|
let path = fs_path.to_abs_path()?;
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let fs = current.fs().read().unwrap();
|
let fs = current.fs().read().unwrap();
|
||||||
|
let masked_mode = mode & !current.process().umask();
|
||||||
|
|
||||||
let file_ref: Arc<dyn File> = fs.open_file(&path, flags, mode)?;
|
let file_ref: Arc<dyn File> = fs.open_file(&path, flags, masked_mode)?;
|
||||||
|
|
||||||
let fd = {
|
let fd = {
|
||||||
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
||||||
|
@ -44,7 +44,7 @@ impl FsView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Open a file on the process. But DO NOT add it to file table.
|
/// Open a file on the process. But DO NOT add it to file table.
|
||||||
pub fn open_file(&self, path: &str, flags: u32, mode: u32) -> Result<Arc<dyn File>> {
|
pub fn open_file(&self, path: &str, flags: u32, mode: FileMode) -> Result<Arc<dyn File>> {
|
||||||
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
||||||
let inode = if creation_flags.no_follow_symlink() {
|
let inode = if creation_flags.no_follow_symlink() {
|
||||||
match self.lookup_inode_no_follow(path) {
|
match self.lookup_inode_no_follow(path) {
|
||||||
@ -73,7 +73,7 @@ impl FsView {
|
|||||||
if !dir_inode.allow_write()? {
|
if !dir_inode.allow_write()? {
|
||||||
return_errno!(EPERM, "file cannot be created");
|
return_errno!(EPERM, "file cannot be created");
|
||||||
}
|
}
|
||||||
dir_inode.create(file_name, FileType::File, mode)?
|
dir_inode.create(file_name, FileType::File, mode.bits())?
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ impl FsView {
|
|||||||
if !dir_inode.allow_write()? {
|
if !dir_inode.allow_write()? {
|
||||||
return_errno!(EPERM, "file cannot be created");
|
return_errno!(EPERM, "file cannot be created");
|
||||||
}
|
}
|
||||||
dir_inode.create(file_name, FileType::File, mode)?
|
dir_inode.create(file_name, FileType::File, mode.bits())?
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ impl INode for HNode {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create(&self, name: &str, type_: FileType, mode: u32) -> Result<Arc<dyn INode>> {
|
fn create(&self, name: &str, type_: FileType, mode: u16) -> Result<Arc<dyn INode>> {
|
||||||
let new_path = self.path.join(name);
|
let new_path = self.path.join(name);
|
||||||
if new_path.exists() {
|
if new_path.exists() {
|
||||||
return Err(FsError::EntryExist);
|
return Err(FsError::EntryExist);
|
||||||
|
@ -97,25 +97,32 @@ pub fn do_timerfd_gettime(fd: FileDesc, curr_value_ptr: *mut itimerspec_t) -> Re
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_creat(path: *const i8, mode: u32) -> Result<isize> {
|
pub fn do_creat(path: *const i8, mode: u16) -> Result<isize> {
|
||||||
let flags =
|
let flags =
|
||||||
AccessMode::O_WRONLY as u32 | (CreationFlags::O_CREAT | CreationFlags::O_TRUNC).bits();
|
AccessMode::O_WRONLY as u32 | (CreationFlags::O_CREAT | CreationFlags::O_TRUNC).bits();
|
||||||
self::do_open(path, flags, mode)
|
self::do_open(path, flags, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_open(path: *const i8, flags: u32, mode: u32) -> Result<isize> {
|
pub fn do_open(path: *const i8, flags: u32, mode: u16) -> Result<isize> {
|
||||||
self::do_openat(AT_FDCWD, path, flags, mode)
|
self::do_openat(AT_FDCWD, path, flags, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u32) -> Result<isize> {
|
pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16) -> Result<isize> {
|
||||||
let path = from_user::clone_cstring_safely(path)?
|
let path = from_user::clone_cstring_safely(path)?
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned();
|
.into_owned();
|
||||||
let fs_path = FsPath::new(&path, dirfd, false)?;
|
let fs_path = FsPath::new(&path, dirfd, false)?;
|
||||||
|
let mode = FileMode::from_bits_truncate(mode);
|
||||||
let fd = file_ops::do_openat(&fs_path, flags, mode)?;
|
let fd = file_ops::do_openat(&fs_path, flags, mode)?;
|
||||||
Ok(fd as isize)
|
Ok(fd as isize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn do_umask(mask: u16) -> Result<isize> {
|
||||||
|
let new_mask = FileMode::from_bits_truncate(mask).to_umask();
|
||||||
|
let old_mask = current!().process().set_umask(new_mask);
|
||||||
|
Ok(old_mask.bits() as isize)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn do_close(fd: FileDesc) -> Result<isize> {
|
pub fn do_close(fd: FileDesc) -> Result<isize> {
|
||||||
file_ops::do_close(fd)?;
|
file_ops::do_close(fd)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
@ -414,15 +421,16 @@ pub fn do_renameat(
|
|||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_mkdir(path: *const i8, mode: usize) -> Result<isize> {
|
pub fn do_mkdir(path: *const i8, mode: u16) -> Result<isize> {
|
||||||
self::do_mkdirat(AT_FDCWD, path, mode)
|
self::do_mkdirat(AT_FDCWD, path, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do_mkdirat(dirfd: i32, path: *const i8, mode: usize) -> Result<isize> {
|
pub fn do_mkdirat(dirfd: i32, path: *const i8, mode: u16) -> Result<isize> {
|
||||||
let path = from_user::clone_cstring_safely(path)?
|
let path = from_user::clone_cstring_safely(path)?
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.into_owned();
|
.into_owned();
|
||||||
let fs_path = FsPath::new(&path, dirfd, false)?;
|
let fs_path = FsPath::new(&path, dirfd, false)?;
|
||||||
|
let mode = FileMode::from_bits_truncate(mode);
|
||||||
file_ops::do_mkdirat(&fs_path, mode)?;
|
file_ops::do_mkdirat(&fs_path, mode)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ use super::endpoint::{end_pair, Endpoint, RelayNotifier};
|
|||||||
use super::*;
|
use super::*;
|
||||||
use events::{Event, EventFilter, Notifier, Observer};
|
use events::{Event, EventFilter, Notifier, Observer};
|
||||||
use fs::channel::Channel;
|
use fs::channel::Channel;
|
||||||
use fs::CreationFlags;
|
|
||||||
use fs::IoEvents;
|
use fs::IoEvents;
|
||||||
|
use fs::{CreationFlags, FileMode};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -75,8 +75,11 @@ impl Stream {
|
|||||||
let corresponding_inode_num = {
|
let corresponding_inode_num = {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let fs = current.fs().read().unwrap();
|
let fs = current.fs().read().unwrap();
|
||||||
let file_ref =
|
let file_ref = fs.open_file(
|
||||||
fs.open_file(path.path_str(), CreationFlags::O_CREAT.bits(), 0o777)?;
|
path.path_str(),
|
||||||
|
CreationFlags::O_CREAT.bits(),
|
||||||
|
FileMode::from_bits(0o777).unwrap(),
|
||||||
|
)?;
|
||||||
file_ref.metadata()?.inode
|
file_ref.metadata()?.inode
|
||||||
};
|
};
|
||||||
*inode_num = Some(corresponding_inode_num);
|
*inode_num = Some(corresponding_inode_num);
|
||||||
|
@ -10,7 +10,7 @@ use super::task::Task;
|
|||||||
use super::thread::{ThreadId, ThreadName};
|
use super::thread::{ThreadId, ThreadName};
|
||||||
use super::{table, task, ProcessRef, ThreadRef};
|
use super::{table, task, ProcessRef, ThreadRef};
|
||||||
use crate::fs::{
|
use crate::fs::{
|
||||||
CreationFlags, File, FileDesc, FileTable, FsView, HostStdioFds, StdinFile, StdoutFile,
|
CreationFlags, File, FileDesc, FileMode, FileTable, FsView, HostStdioFds, StdinFile, StdoutFile,
|
||||||
};
|
};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::vm::ProcessVM;
|
use crate::vm::ProcessVM;
|
||||||
@ -285,6 +285,7 @@ fn new_process_common(
|
|||||||
process_builder
|
process_builder
|
||||||
.vm(vm_ref)
|
.vm(vm_ref)
|
||||||
.exec_path(&elf_path)
|
.exec_path(&elf_path)
|
||||||
|
.umask(parent.umask())
|
||||||
.parent(parent)
|
.parent(parent)
|
||||||
.task(task)
|
.task(task)
|
||||||
.sched(sched_ref)
|
.sched(sched_ref)
|
||||||
@ -339,12 +340,11 @@ fn init_files(
|
|||||||
oflag,
|
oflag,
|
||||||
fd,
|
fd,
|
||||||
} => {
|
} => {
|
||||||
let file_ref =
|
let file_ref = current_ref.fs().read().unwrap().open_file(
|
||||||
current_ref
|
path.as_str(),
|
||||||
.fs()
|
oflag,
|
||||||
.read()
|
FileMode::from_bits_truncate(mode as u16),
|
||||||
.unwrap()
|
)?;
|
||||||
.open_file(path.as_str(), oflag, mode)?;
|
|
||||||
let creation_flags = CreationFlags::from_bits_truncate(oflag);
|
let creation_flags = CreationFlags::from_bits_truncate(oflag);
|
||||||
cloned_file_table.put_at(fd, file_ref, creation_flags.must_close_on_spawn());
|
cloned_file_table.put_at(fd, file_ref, creation_flags.must_close_on_spawn());
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use super::super::{
|
|||||||
SchedAgentRef,
|
SchedAgentRef,
|
||||||
};
|
};
|
||||||
use super::{Process, ProcessInner};
|
use super::{Process, ProcessInner};
|
||||||
|
use crate::fs::FileMode;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::signal::{SigDispositions, SigQueues, SigSet};
|
use crate::signal::{SigDispositions, SigQueues, SigSet};
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ pub struct ProcessBuilder {
|
|||||||
vm: Option<ProcessVMRef>,
|
vm: Option<ProcessVMRef>,
|
||||||
// Optional fields, which have reasonable default values
|
// Optional fields, which have reasonable default values
|
||||||
exec_path: Option<String>,
|
exec_path: Option<String>,
|
||||||
|
umask: Option<FileMode>,
|
||||||
parent: Option<ProcessRef>,
|
parent: Option<ProcessRef>,
|
||||||
no_parent: bool,
|
no_parent: bool,
|
||||||
sig_dispositions: Option<SigDispositions>,
|
sig_dispositions: Option<SigDispositions>,
|
||||||
@ -29,6 +31,7 @@ impl ProcessBuilder {
|
|||||||
thread_builder: Some(thread_builder),
|
thread_builder: Some(thread_builder),
|
||||||
vm: None,
|
vm: None,
|
||||||
exec_path: None,
|
exec_path: None,
|
||||||
|
umask: None,
|
||||||
parent: None,
|
parent: None,
|
||||||
no_parent: false,
|
no_parent: false,
|
||||||
sig_dispositions: None,
|
sig_dispositions: None,
|
||||||
@ -45,6 +48,11 @@ impl ProcessBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn umask(mut self, umask: FileMode) -> Self {
|
||||||
|
self.umask = Some(umask);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parent(mut self, parent: ProcessRef) -> Self {
|
pub fn parent(mut self, parent: ProcessRef) -> Self {
|
||||||
self.parent = Some(parent);
|
self.parent = Some(parent);
|
||||||
self
|
self
|
||||||
@ -108,6 +116,7 @@ impl ProcessBuilder {
|
|||||||
// Build a new process
|
// Build a new process
|
||||||
let new_process = {
|
let new_process = {
|
||||||
let exec_path = self.exec_path.take().unwrap_or_default();
|
let exec_path = self.exec_path.take().unwrap_or_default();
|
||||||
|
let umask = RwLock::new(self.umask.unwrap_or(FileMode::default_umask()));
|
||||||
let parent = self.parent.take().map(|parent| RwLock::new(parent));
|
let parent = self.parent.take().map(|parent| RwLock::new(parent));
|
||||||
let inner = SgxMutex::new(ProcessInner::new());
|
let inner = SgxMutex::new(ProcessInner::new());
|
||||||
let sig_dispositions = RwLock::new(self.sig_dispositions.unwrap_or_default());
|
let sig_dispositions = RwLock::new(self.sig_dispositions.unwrap_or_default());
|
||||||
@ -116,6 +125,7 @@ impl ProcessBuilder {
|
|||||||
Arc::new(Process {
|
Arc::new(Process {
|
||||||
pid,
|
pid,
|
||||||
exec_path,
|
exec_path,
|
||||||
|
umask,
|
||||||
parent,
|
parent,
|
||||||
inner,
|
inner,
|
||||||
sig_dispositions,
|
sig_dispositions,
|
||||||
|
@ -2,6 +2,7 @@ use std::fmt;
|
|||||||
|
|
||||||
use super::wait::WaitQueue;
|
use super::wait::WaitQueue;
|
||||||
use super::{ForcedExitStatus, ProcessRef, TermStatus, ThreadRef};
|
use super::{ForcedExitStatus, ProcessRef, TermStatus, ThreadRef};
|
||||||
|
use crate::fs::FileMode;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::signal::{SigDispositions, SigNum, SigQueues};
|
use crate::signal::{SigDispositions, SigNum, SigQueues};
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ pub struct Process {
|
|||||||
// Mutable info
|
// Mutable info
|
||||||
parent: Option<RwLock<ProcessRef>>,
|
parent: Option<RwLock<ProcessRef>>,
|
||||||
inner: SgxMutex<ProcessInner>,
|
inner: SgxMutex<ProcessInner>,
|
||||||
|
umask: RwLock<FileMode>,
|
||||||
// Signal
|
// Signal
|
||||||
sig_dispositions: RwLock<SigDispositions>,
|
sig_dispositions: RwLock<SigDispositions>,
|
||||||
sig_queues: RwLock<SigQueues>,
|
sig_queues: RwLock<SigQueues>,
|
||||||
@ -99,6 +101,19 @@ impl Process {
|
|||||||
&self.exec_path
|
&self.exec_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the file mode creation mask
|
||||||
|
pub fn umask(&self) -> FileMode {
|
||||||
|
self.umask.read().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the file mode creation mask, return the previous value
|
||||||
|
pub fn set_umask(&self, new_mask: FileMode) -> FileMode {
|
||||||
|
let mut mask = self.umask.write().unwrap();
|
||||||
|
let old_mask = mask.clone();
|
||||||
|
*mask = new_mask;
|
||||||
|
old_mask
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the signal queues for process-directed signals.
|
/// Get the signal queues for process-directed signals.
|
||||||
pub fn sig_queues(&self) -> &RwLock<SigQueues> {
|
pub fn sig_queues(&self) -> &RwLock<SigQueues> {
|
||||||
&self.sig_queues
|
&self.sig_queues
|
||||||
|
@ -29,8 +29,9 @@ use crate::fs::{
|
|||||||
do_lseek, do_lstat, do_mkdir, do_mkdirat, do_mount_rootfs, do_open, do_openat, do_pipe,
|
do_lseek, do_lstat, do_mkdir, do_mkdirat, do_mount_rootfs, do_open, do_openat, do_pipe,
|
||||||
do_pipe2, do_pread, do_pwrite, do_read, do_readlink, do_readlinkat, do_readv, do_rename,
|
do_pipe2, do_pread, do_pwrite, do_read, do_readlink, do_readlinkat, do_readv, do_rename,
|
||||||
do_renameat, do_rmdir, do_sendfile, do_stat, do_statfs, do_symlink, do_symlinkat, do_sync,
|
do_renameat, do_rmdir, do_sendfile, do_stat, do_statfs, do_symlink, do_symlinkat, do_sync,
|
||||||
do_timerfd_create, do_timerfd_gettime, do_timerfd_settime, do_truncate, do_unlink, do_unlinkat,
|
do_timerfd_create, do_timerfd_gettime, do_timerfd_settime, do_truncate, do_umask, do_unlink,
|
||||||
do_write, do_writev, iovec_t, AsTimer, File, FileDesc, FileRef, HostStdioFds, Stat, Statfs,
|
do_unlinkat, do_write, do_writev, iovec_t, AsTimer, File, FileDesc, FileRef, HostStdioFds,
|
||||||
|
Stat, Statfs,
|
||||||
};
|
};
|
||||||
use crate::interrupt::{do_handle_interrupt, sgx_interrupt_info_t};
|
use crate::interrupt::{do_handle_interrupt, sgx_interrupt_info_t};
|
||||||
use crate::misc::{resource_t, rlimit_t, sysinfo_t, utsname_t};
|
use crate::misc::{resource_t, rlimit_t, sysinfo_t, utsname_t};
|
||||||
@ -89,7 +90,7 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
// TODO: Unify the use of C types. For example, u8 or i8 or char_c for C string?
|
// TODO: Unify the use of C types. For example, u8 or i8 or char_c for C string?
|
||||||
(Read = 0) => do_read(fd: FileDesc, buf: *mut u8, size: usize),
|
(Read = 0) => do_read(fd: FileDesc, buf: *mut u8, size: usize),
|
||||||
(Write = 1) => do_write(fd: FileDesc, buf: *const u8, size: usize),
|
(Write = 1) => do_write(fd: FileDesc, buf: *const u8, size: usize),
|
||||||
(Open = 2) => do_open(path: *const i8, flags: u32, mode: u32),
|
(Open = 2) => do_open(path: *const i8, flags: u32, mode: u16),
|
||||||
(Close = 3) => do_close(fd: FileDesc),
|
(Close = 3) => do_close(fd: FileDesc),
|
||||||
(Stat = 4) => do_stat(path: *const i8, stat_buf: *mut Stat),
|
(Stat = 4) => do_stat(path: *const i8, stat_buf: *mut Stat),
|
||||||
(Fstat = 5) => do_fstat(fd: FileDesc, stat_buf: *mut Stat),
|
(Fstat = 5) => do_fstat(fd: FileDesc, stat_buf: *mut Stat),
|
||||||
@ -170,9 +171,9 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
(Chdir = 80) => do_chdir(path: *const i8),
|
(Chdir = 80) => do_chdir(path: *const i8),
|
||||||
(Fchdir = 81) => do_fchdir(fd: FileDesc),
|
(Fchdir = 81) => do_fchdir(fd: FileDesc),
|
||||||
(Rename = 82) => do_rename(oldpath: *const i8, newpath: *const i8),
|
(Rename = 82) => do_rename(oldpath: *const i8, newpath: *const i8),
|
||||||
(Mkdir = 83) => do_mkdir(path: *const i8, mode: usize),
|
(Mkdir = 83) => do_mkdir(path: *const i8, mode: u16),
|
||||||
(Rmdir = 84) => do_rmdir(path: *const i8),
|
(Rmdir = 84) => do_rmdir(path: *const i8),
|
||||||
(Creat = 85) => do_creat(path: *const i8, mode: u32),
|
(Creat = 85) => do_creat(path: *const i8, mode: u16),
|
||||||
(Link = 86) => do_link(oldpath: *const i8, newpath: *const i8),
|
(Link = 86) => do_link(oldpath: *const i8, newpath: *const i8),
|
||||||
(Unlink = 87) => do_unlink(path: *const i8),
|
(Unlink = 87) => do_unlink(path: *const i8),
|
||||||
(Symlink = 88) => do_symlink(target: *const i8, link_path: *const i8),
|
(Symlink = 88) => do_symlink(target: *const i8, link_path: *const i8),
|
||||||
@ -182,7 +183,7 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
(Chown = 92) => do_chown(path: *const i8, uid: u32, gid: u32),
|
(Chown = 92) => do_chown(path: *const i8, uid: u32, gid: u32),
|
||||||
(Fchown = 93) => do_fchown(fd: FileDesc, uid: u32, gid: u32),
|
(Fchown = 93) => do_fchown(fd: FileDesc, uid: u32, gid: u32),
|
||||||
(Lchown = 94) => do_lchown(path: *const i8, uid: u32, gid: u32),
|
(Lchown = 94) => do_lchown(path: *const i8, uid: u32, gid: u32),
|
||||||
(Umask = 95) => handle_unsupported(),
|
(Umask = 95) => do_umask(mask: u16),
|
||||||
(Gettimeofday = 96) => do_gettimeofday(tv_u: *mut timeval_t),
|
(Gettimeofday = 96) => do_gettimeofday(tv_u: *mut timeval_t),
|
||||||
(Getrlimit = 97) => handle_unsupported(),
|
(Getrlimit = 97) => handle_unsupported(),
|
||||||
(Getrusage = 98) => handle_unsupported(),
|
(Getrusage = 98) => handle_unsupported(),
|
||||||
@ -344,8 +345,8 @@ macro_rules! process_syscall_table_with_callback {
|
|||||||
(InotifyAddWatch = 254) => handle_unsupported(),
|
(InotifyAddWatch = 254) => handle_unsupported(),
|
||||||
(InotifyRmWatch = 255) => handle_unsupported(),
|
(InotifyRmWatch = 255) => handle_unsupported(),
|
||||||
(MigratePages = 256) => handle_unsupported(),
|
(MigratePages = 256) => handle_unsupported(),
|
||||||
(Openat = 257) => do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u32),
|
(Openat = 257) => do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16),
|
||||||
(Mkdirat = 258) => do_mkdirat(dirfd: i32, path: *const i8, mode: usize),
|
(Mkdirat = 258) => do_mkdirat(dirfd: i32, path: *const i8, mode: u16),
|
||||||
(Mknodat = 259) => handle_unsupported(),
|
(Mknodat = 259) => handle_unsupported(),
|
||||||
(Fchownat = 260) => do_fchownat(dirfd: i32, path: *const i8, uid: u32, gid: u32, flags: i32),
|
(Fchownat = 260) => do_fchownat(dirfd: i32, path: *const i8, uid: u32, gid: u32, flags: i32),
|
||||||
(Futimesat = 261) => handle_unsupported(),
|
(Futimesat = 261) => handle_unsupported(),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::fs::{AccessMode, CreationFlags, FsView};
|
use crate::fs::{AccessMode, CreationFlags, FileMode, FsView};
|
||||||
use resolv_conf::*;
|
use resolv_conf::*;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::str;
|
use std::str;
|
||||||
@ -11,7 +11,7 @@ pub fn write_resolv_conf() -> Result<()> {
|
|||||||
let resolv_conf_file = fs_view.open_file(
|
let resolv_conf_file = fs_view.open_file(
|
||||||
RESOLV_CONF_PATH,
|
RESOLV_CONF_PATH,
|
||||||
AccessMode::O_RDWR as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(),
|
AccessMode::O_RDWR as u32 | CreationFlags::O_CREAT.bits() | CreationFlags::O_TRUNC.bits(),
|
||||||
0o666,
|
FileMode::from_bits(0o666).unwrap(),
|
||||||
)?;
|
)?;
|
||||||
let resolv_conf_str = RESOLV_CONF_STR.read().unwrap();
|
let resolv_conf_str = RESOLV_CONF_STR.read().unwrap();
|
||||||
match &*resolv_conf_str {
|
match &*resolv_conf_str {
|
||||||
|
@ -19,7 +19,7 @@ TESTS ?= env empty hello_world malloc mmap file fs_perms getpid spawn sched pipe
|
|||||||
truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info resolv_conf rlimit \
|
truncate readdir mkdir open stat link symlink chmod chown tls pthread system_info resolv_conf rlimit \
|
||||||
server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group \
|
server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group \
|
||||||
ioctl fcntl eventfd emulate_syscall access signal sysinfo prctl rename procfs wait \
|
ioctl fcntl eventfd emulate_syscall access signal sysinfo prctl rename procfs wait \
|
||||||
spawn_attribute exec statfs
|
spawn_attribute exec statfs umask
|
||||||
# Benchmarks: need to be compiled and run by bench-% target
|
# Benchmarks: need to be compiled and run by bench-% target
|
||||||
BENCHES := spawn_and_exit_latency pipe_throughput unix_socket_throughput
|
BENCHES := spawn_and_exit_latency pipe_throughput unix_socket_throughput
|
||||||
|
|
||||||
|
5
test/umask/Makefile
Normal file
5
test/umask/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
include ../test_common.mk
|
||||||
|
|
||||||
|
EXTRA_C_FLAGS :=
|
||||||
|
EXTRA_LINK_FLAGS :=
|
||||||
|
BIN_ARGS :=
|
100
test/umask/main.c
Normal file
100
test/umask/main.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "test_fs.h"
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Helper function
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static int remove_file(const char *file_path) {
|
||||||
|
int ret;
|
||||||
|
ret = unlink(file_path);
|
||||||
|
if (ret < 0) {
|
||||||
|
THROW_ERROR("failed to unlink the created file");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_create_file_with_umask(const char *file_path, mode_t mask) {
|
||||||
|
mode_t mode = 00666;
|
||||||
|
int fd = creat(file_path, mode);
|
||||||
|
if (fd < 0) {
|
||||||
|
THROW_ERROR("failed to create file");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat stat_buf;
|
||||||
|
if (fstat(fd, &stat_buf) < 0) {
|
||||||
|
THROW_ERROR("failed to stat file");
|
||||||
|
}
|
||||||
|
mode_t actual_mode = stat_buf.st_mode & 00777;
|
||||||
|
if (actual_mode != (mode & ~mask)) {
|
||||||
|
THROW_ERROR("failed to check the mode with umask(%o), actual_mode is: %o", mask,
|
||||||
|
actual_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Test cases for umask
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#define DEFAULT_UMASK (00022)
|
||||||
|
|
||||||
|
static int __test_create_file_with_default_umask(const char *file_path) {
|
||||||
|
if (check_create_file_with_umask(file_path, DEFAULT_UMASK) < 0) {
|
||||||
|
THROW_ERROR("failed to check default umask");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __test_umask(const char *file_path) {
|
||||||
|
mode_t new_mask = 00066;
|
||||||
|
int old_mask = umask(new_mask);
|
||||||
|
if (old_mask != DEFAULT_UMASK) {
|
||||||
|
THROW_ERROR("failed to get correct default mask");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_create_file_with_umask(file_path, new_mask) < 0) {
|
||||||
|
THROW_ERROR("failed to check default umask");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int(*test_file_func_t)(const char *);
|
||||||
|
|
||||||
|
static int test_file_framework(test_file_func_t fn) {
|
||||||
|
const char *file_path = "/root/test_filesystem_umask.txt";
|
||||||
|
|
||||||
|
if (fn(file_path) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (remove_file(file_path) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_create_file_with_default_umask() {
|
||||||
|
return test_file_framework(__test_create_file_with_default_umask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_umask() {
|
||||||
|
return test_file_framework(__test_umask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// Test suite main
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
static test_case_t test_cases[] = {
|
||||||
|
TEST_CASE(test_create_file_with_default_umask),
|
||||||
|
TEST_CASE(test_umask),
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[]) {
|
||||||
|
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user