From e30ed9ab6abbf5b90e2d161718973ebc814a8306 Mon Sep 17 00:00:00 2001 From: Ibuki Omatsu Date: Thu, 18 Dec 2025 01:31:04 +0000 Subject: [PATCH] Introduce syscall6. Add unlinkat and remove unlink and rmdir. --- Cargo.lock | 5 +- Cargo.toml | 2 +- src/arch/aarch64/interrupt/exception.rs | 5 +- src/arch/aarch64/interrupt/handler.rs | 5 ++ src/arch/riscv64/interrupt/exception.rs | 2 +- src/arch/riscv64/interrupt/handler.rs | 6 ++ src/arch/x86/interrupt/syscall.rs | 1 + src/arch/x86_64/interrupt/handler.rs | 6 +- src/arch/x86_64/interrupt/syscall.rs | 1 + src/context/arch/aarch64.rs | 4 +- src/context/arch/riscv64.rs | 6 +- src/context/arch/x86.rs | 3 +- src/context/arch/x86_64.rs | 3 +- src/debugger.rs | 4 +- src/panic.rs | 7 ++- src/scheme/mod.rs | 25 ++++++-- src/scheme/proc.rs | 18 +++++- src/scheme/root.rs | 38 +++++++++-- src/scheme/sys/syscall.rs | 4 +- src/scheme/user.rs | 25 +++----- src/syscall/debug.rs | 34 ++++++---- src/syscall/fs.rs | 83 +++++++++++-------------- src/syscall/mod.rs | 29 ++++++--- 23 files changed, 204 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aa5bb9a57..c993903372 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,8 +208,9 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7" [[package]] name = "redox_syscall" -version = "0.5.18" -source = "git+https://gitlab.redox-os.org/redox-os/syscall.git?branch=master#2d346f1d610a358d74cd40360cf7e5dcfc2120d7" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" dependencies = [ "bitflags 2.9.4", ] diff --git a/Cargo.toml b/Cargo.toml index 1fe569eefe..dc6f97dae7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ bitflags = "2" hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] } linked_list_allocator = "0.9.0" redox-path = "0.2.0" -redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", branch = "master", default-features = false } +redox_syscall = { version = "0.6.0", default-features = false } rmm = { path = "rmm", default-features = false } slab = { version = "0.4", default-features = false } spin = { version = "0.9.8" } diff --git a/src/arch/aarch64/interrupt/exception.rs b/src/arch/aarch64/interrupt/exception.rs index c4f9dec8c5..63c68918ce 100644 --- a/src/arch/aarch64/interrupt/exception.rs +++ b/src/arch/aarch64/interrupt/exception.rs @@ -6,7 +6,7 @@ use crate::{ exception_stack, memory::{ArchIntCtx, GenericPfFlags}, sync::CleanLockToken, - syscall::{self, flag::*}, + syscall, }; use super::InterruptStack; @@ -189,7 +189,8 @@ exception_stack!(synchronous_exception_at_el0, |stack| { let scratch = &stack.scratch; let mut token = unsafe { CleanLockToken::new() }; let ret = syscall::syscall( - scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, &mut token, + scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, scratch.x5, + &mut token, ); stack.scratch.x0 = ret; } diff --git a/src/arch/aarch64/interrupt/handler.rs b/src/arch/aarch64/interrupt/handler.rs index 6c7a0359e3..0fc15dc559 100644 --- a/src/arch/aarch64/interrupt/handler.rs +++ b/src/arch/aarch64/interrupt/handler.rs @@ -138,6 +138,11 @@ impl InterruptStack { pub fn instr_pointer(&self) -> usize { self.iret.elr_el1 } + pub fn set_arg1(&mut self, arg_opt: Option) { + if let Some(arg) = arg_opt { + self.scratch.x1 = arg; + } + } pub fn dump(&self) { self.iret.dump(); self.scratch.dump(); diff --git a/src/arch/riscv64/interrupt/exception.rs b/src/arch/riscv64/interrupt/exception.rs index ac8d81f935..b580f2e27e 100644 --- a/src/arch/riscv64/interrupt/exception.rs +++ b/src/arch/riscv64/interrupt/exception.rs @@ -161,7 +161,7 @@ unsafe fn handle_user_exception(scause: usize, regs: &mut InterruptStack) { if scause == USERMODE_ECALL { let r = &mut regs.registers; regs.iret.sepc += 4; // skip ecall - let ret = syscall::syscall(r.x17, r.x10, r.x11, r.x12, r.x13, r.x14, &mut token); + let ret = syscall::syscall(r.x17, r.x10, r.x11, r.x12, r.x13, r.x14, r.x15, &mut token); r.x10 = ret; return; } diff --git a/src/arch/riscv64/interrupt/handler.rs b/src/arch/riscv64/interrupt/handler.rs index 070a4932c7..1be5b9298c 100644 --- a/src/arch/riscv64/interrupt/handler.rs +++ b/src/arch/riscv64/interrupt/handler.rs @@ -122,6 +122,12 @@ impl InterruptStack { self.registers.x10 = ret; } + pub fn set_arg1(&mut self, arg_opt: Option) { + if let Some(arg) = arg_opt { + self.registers.x11 = arg; + } + } + pub fn dump(&self) { self.iret.dump(); self.registers.dump(); diff --git a/src/arch/x86/interrupt/syscall.rs b/src/arch/x86/interrupt/syscall.rs index 9d23a5b640..22895c11ac 100644 --- a/src/arch/x86/interrupt/syscall.rs +++ b/src/arch/x86/interrupt/syscall.rs @@ -38,6 +38,7 @@ interrupt_stack!(syscall, |stack| { scratch.edx, preserved.esi, preserved.edi, + preserved.ebp, &mut token, ); stack.scratch.eax = ret; diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index 1cd82dac05..2186dee468 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -120,7 +120,11 @@ impl InterruptStack { pub fn set_instr_pointer(&mut self, rip: usize) { self.iret.rip = rip; } - + pub fn set_arg1(&mut self, arg_opt: Option) { + if let Some(arg) = arg_opt { + self.scratch.rsi = arg; + } + } pub fn dump(&self) { self.iret.dump(); self.scratch.dump(); diff --git a/src/arch/x86_64/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs index aa13bb75f7..483914b8dc 100644 --- a/src/arch/x86_64/interrupt/syscall.rs +++ b/src/arch/x86_64/interrupt/syscall.rs @@ -83,6 +83,7 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack) scratch.rdx, scratch.r10, scratch.r8, + scratch.r9, &mut token, ); (*stack).scratch.rax = ret; diff --git a/src/context/arch/aarch64.rs b/src/context/arch/aarch64.rs index f50550332a..bf580d4b9b 100644 --- a/src/context/arch/aarch64.rs +++ b/src/context/arch/aarch64.rs @@ -153,14 +153,14 @@ impl super::Context { ptr::write(self.kfx.as_mut_ptr() as *mut FloatRegisters, new); } } - pub fn current_syscall(&self) -> Option<[usize; 6]> { + pub fn current_syscall(&self) -> Option<[usize; 7]> { if !self.inside_syscall { return None; } let regs = self.regs()?; let scratch = ®s.scratch; Some([ - scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, + scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, scratch.x5, ]) } diff --git a/src/context/arch/riscv64.rs b/src/context/arch/riscv64.rs index e7c6765fe7..7d763ddcbe 100644 --- a/src/context/arch/riscv64.rs +++ b/src/context/arch/riscv64.rs @@ -88,13 +88,15 @@ impl super::Context { unimplemented!() } - pub fn current_syscall(&self) -> Option<[usize; 6]> { + pub fn current_syscall(&self) -> Option<[usize; 7]> { if !self.inside_syscall { return None; } let regs = self.regs()?; let regs = ®s.registers; - Some([regs.x17, regs.x10, regs.x11, regs.x12, regs.x13, regs.x14]) + Some([ + regs.x17, regs.x10, regs.x11, regs.x12, regs.x13, regs.x14, regs.x15, + ]) } pub(crate) fn write_current_env_regs(&mut self, regs: EnvRegisters) -> Result<()> { diff --git a/src/context/arch/x86.rs b/src/context/arch/x86.rs index f5b01f8dec..baea9a32d0 100644 --- a/src/context/arch/x86.rs +++ b/src/context/arch/x86.rs @@ -145,7 +145,7 @@ impl super::Context { } } } - pub fn current_syscall(&self) -> Option<[usize; 6]> { + pub fn current_syscall(&self) -> Option<[usize; 7]> { if !self.inside_syscall { return None; } @@ -157,6 +157,7 @@ impl super::Context { regs.scratch.edx, regs.preserved.esi, regs.preserved.edi, + regs.preserved.ebp, ]) } diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs index a84ba75ff7..833bc60b52 100644 --- a/src/context/arch/x86_64.rs +++ b/src/context/arch/x86_64.rs @@ -161,7 +161,7 @@ impl super::Context { } } - pub(crate) fn current_syscall(&self) -> Option<[usize; 6]> { + pub(crate) fn current_syscall(&self) -> Option<[usize; 7]> { if !self.inside_syscall { return None; } @@ -174,6 +174,7 @@ impl super::Context { scratch.rdx, scratch.r10, scratch.r8, + scratch.r9, ]) } diff --git a/src/debugger.rs b/src/debugger.rs index 6d8bbf3bca..cd43dce923 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -65,10 +65,10 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL if !context.status_reason.is_empty() { println!("reason: {}", context.status_reason); } - if let Some([a, b, c, d, e, f]) = context.current_syscall() { + if let Some([a, b, c, d, e, f, g]) = context.current_syscall() { println!( "syscall: {}", - crate::syscall::debug::format_call(a, b, c, d, e, f) + crate::syscall::debug::format_call(a, b, c, d, e, f, g) ); } if let Some(ref addr_space) = context.addr_space { diff --git a/src/panic.rs b/src/panic.rs index df8512d69d..4917187665 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -57,8 +57,11 @@ fn panic_handler_inner(info: &PanicInfo) -> ! { let context = context_lock.read(token.token()); println!("NAME: {}, DEBUG ID: {}", context.name, context.debug_id); - if let Some([a, b, c, d, e, f]) = context.current_syscall() { - println!("SYSCALL: {}", syscall::debug::format_call(a, b, c, d, e, f)); + if let Some([a, b, c, d, e, f, g]) = context.current_syscall() { + println!( + "SYSCALL: {}", + syscall::debug::format_call(a, b, c, d, e, f, g) + ); } } diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index eabc78a729..563813b8c6 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -559,10 +559,14 @@ pub trait KernelScheme: Send + Sync + 'static { ) -> Result { Ok(0) } - fn rmdir(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> { - Err(Error::new(ENOENT)) - } - fn unlink(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> { + fn unlinkat( + &self, + file: usize, + path: &str, + flags: usize, + ctx: CallerCtx, + token: &mut CleanLockToken, + ) -> Result<()> { Err(Error::new(ENOENT)) } fn close(&self, id: usize, token: &mut CleanLockToken) -> Result<()> { @@ -611,6 +615,19 @@ pub struct CallerCtx { pub uid: u32, pub gid: u32, } +impl CallerCtx { + pub fn filter_uid_gid(self, euid: u32, egid: u32) -> Self { + if self.uid == 0 && self.gid == 0 { + Self { + pid: self.pid, + uid: euid, + gid: egid, + } + } else { + self + } + } +} #[derive(Clone)] pub enum KernelSchemes { diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index eec51138da..b59340037c 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -131,6 +131,7 @@ enum ContextHandle { new: Arc, new_sp: usize, new_ip: usize, + arg1: Option, }, CurrentFiletable, @@ -444,12 +445,19 @@ impl KernelScheme for ProcScheme { new, new_sp, new_ip, + arg1, }, } => { let _ = try_stop_context(context, token, |context: &mut Context| { let regs = context.regs_mut().ok_or(Error::new(EBADFD))?; regs.set_instr_pointer(new_ip); regs.set_stack_pointer(new_sp); + #[cfg(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64" + ))] + regs.set_arg1(arg1); Ok(context.set_addr_space(Some(new))) })?; @@ -1089,6 +1097,7 @@ impl ContextHandle { let addrspace_fd = iter.next().ok_or(Error::new(EINVAL))??; let sp = iter.next().ok_or(Error::new(EINVAL))??; let ip = iter.next().ok_or(Error::new(EINVAL))??; + let arg1 = iter.next().transpose()?; let (hopefully_this_scheme, number) = extract_scheme_number(addrspace_fd, token)?; verify_scheme(hopefully_this_scheme)?; @@ -1108,10 +1117,17 @@ impl ContextHandle { new: Arc::clone(addrspace), new_sp: sp, new_ip: ip, + arg1, }, }; - Ok(3 * mem::size_of::()) + let written = if arg1.is_some() { + 4 * mem::size_of::() + } else { + 3 * mem::size_of::() + }; + + Ok(written) } Self::MmapMinAddr(ref addrspace) => { let val = buf.read_usize()?; diff --git a/src/scheme/root.rs b/src/scheme/root.rs index a74d95e572..cbfe7d2d89 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -81,7 +81,10 @@ impl KernelScheme for RootScheme { let new_close = flags & O_EXLOCK == O_EXLOCK; if !v2 { - error!("Context {} tried to open a v1 scheme", context::current().read(token.token()).name); + error!( + "Context {} tried to open a v1 scheme", + context::current().read(token.token()).name + ); return Err(Error::new(EINVAL)); } if !new_close { @@ -138,21 +141,44 @@ impl KernelScheme for RootScheme { } } - fn unlink(&self, path: &str, ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> { + fn unlinkat( + &self, + fd: usize, + path: &str, + _flags: usize, + ctx: CallerCtx, + token: &mut CleanLockToken, + ) -> Result<()> { let path = path.trim_matches('/'); + let ens = { + let handles = self.handles.read(token.token()); + let Handle::List { ens } = handles.get(&fd).ok_or(Error::new(ENOENT))? else { + return Err(Error::new(EPERM)); + }; + *ens + }; + if ctx.uid != 0 { return Err(Error::new(EACCES)); } + + { + let schemes = scheme::schemes(token.token()); + if schemes.get_name(ens, path).is_none() { + return Err(Error::new(ENODEV)); + } + } + let inner = { let handles = self.handles.read(token.token()); handles .iter() .find_map(|(_id, handle)| { - if let Handle::Scheme(inner) = handle { - if path == inner.name.as_ref() { - return Some(inner.clone()); - } + if let Handle::Scheme(inner) = handle + && path == inner.name.as_ref() + { + return Some(inner.clone()); } None }) diff --git a/src/scheme/sys/syscall.rs b/src/scheme/sys/syscall.rs index 1d4dc7892b..8a72b9bcb0 100644 --- a/src/scheme/sys/syscall.rs +++ b/src/scheme/sys/syscall.rs @@ -21,11 +21,11 @@ pub fn resource(token: &mut CleanLockToken) -> Result> { for &(id, ref name, sc) in rows.iter() { let _ = writeln!(string, "{}: {}", id, name); - if let Some([a, b, c, d, e, f]) = sc { + if let Some([a, b, c, d, e, f, g]) = sc { let _ = writeln!( string, " {}", - syscall::debug::format_call(a, b, c, d, e, f) + syscall::debug::format_call(a, b, c, d, e, f, g) ); } } diff --git a/src/scheme/user.rs b/src/scheme/user.rs index e28f260d30..b63ac29f8c 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -1497,24 +1497,19 @@ impl KernelScheme for UserScheme { } } - fn rmdir(&self, path: &str, _ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> { + fn unlinkat( + &self, + file: usize, + path: &str, + flags: usize, + _ctx: CallerCtx, + token: &mut CleanLockToken, + ) -> Result<()> { let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; let mut address = inner.copy_and_capture_tail(path.as_bytes(), token)?; inner.call( - Opcode::Rmdir, - [address.base(), address.len()], - address.span(), - token, - )?; - Ok(()) - } - - fn unlink(&self, path: &str, _ctx: CallerCtx, token: &mut CleanLockToken) -> Result<()> { - let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?; - let mut address = inner.copy_and_capture_tail(path.as_bytes(), token)?; - inner.call( - Opcode::Unlink, - [address.base(), address.len()], + Opcode::UnlinkAt, + [file, address.base(), address.len(), flags], address.span(), token, )?; diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs index f65965b8d2..fc6586265b 100644 --- a/src/syscall/debug.rs +++ b/src/syscall/debug.rs @@ -42,20 +42,28 @@ unsafe fn read_struct(ptr: usize) -> Result { } //TODO: calling format_call with arguments from another process space will not work -pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String { +pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize) -> String { match a { SYS_OPEN => format!( "open({:?}, {:#X})", debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())), d ), - SYS_RMDIR => format!( - "rmdir({:?})", - debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())), + SYS_OPENAT => format!( + "openat({} {:?}, {:#0x}, {}, {})", + b, + debug_path(c, d).as_ref().map(|p| ByteStr(p.as_bytes())), + e, + f, + g ), - SYS_UNLINK => format!( - "unlink({:?})", - debug_path(b, c).as_ref().map(|p| ByteStr(p.as_bytes())), + SYS_UNLINKAT => format!( + "unlinkat({} {:?}, {:#0x}, {}, {})", + b, + debug_path(c, d).as_ref().map(|p| ByteStr(p.as_bytes())), + e, + f, + g, ), SYS_CLOSE => format!("close({})", b), SYS_DUP => format!( @@ -186,8 +194,8 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - ), SYS_YIELD => format!("yield()"), _ => format!( - "UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})", - a, a, b, c, d, e, f + "UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X}, {:#X})", + a, a, b, c, d, e, f, g ), } } @@ -219,7 +227,7 @@ impl SyscallDebugInfo { } #[cfg_attr(feature = "syscall_debug", inline)] -pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) { +pub fn debug_start([a, b, c, d, e, f, g]: [usize; 7], token: &mut CleanLockToken) { if cfg!(not(feature = "syscall_debug")) { return; } @@ -252,7 +260,7 @@ pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) { // Do format_call outside print! so possible exception handlers cannot reentrantly // deadlock. - let string = format_call(a, b, c, d, e, f); + let string = format_call(a, b, c, d, e, f, g); println!("{}", string); crate::time::monotonic() @@ -271,7 +279,7 @@ pub fn debug_start([a, b, c, d, e, f]: [usize; 6], token: &mut CleanLockToken) { #[cfg_attr(feature = "syscall_debug", inline)] pub fn debug_end( - [a, b, c, d, e, f]: [usize; 6], + [a, b, c, d, e, f, g]: [usize; 7], result: Result, token: &mut CleanLockToken, ) { @@ -297,7 +305,7 @@ pub fn debug_end( // Do format_call outside print! so possible exception handlers cannot reentrantly // deadlock. - let string = format_call(a, b, c, d, e, f); + let string = format_call(a, b, c, d, e, f, g); print!("{} = ", string); match result { diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 1a4306e2ce..7cc486c509 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -1,4 +1,5 @@ //! Filesystem syscalls + use core::{mem::size_of, num::NonZeroUsize}; use alloc::{string::String, sync::Arc, vec::Vec}; @@ -145,6 +146,8 @@ pub fn openat( raw_path: UserSliceRo, flags: usize, fcntl_flags: u32, + euid: u32, + egid: u32, token: &mut CleanLockToken, ) -> Result { let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?; @@ -161,7 +164,10 @@ pub fn openat( let description = pipe.description.read(); - let caller_ctx = context::current().read(token.token()).caller_ctx(); + let caller_ctx = context::current() + .read(token.token()) + .caller_ctx() + .filter_uid_gid(euid, egid); let new_description = { let scheme = scheme::schemes(token.token()) @@ -185,7 +191,7 @@ pub fn openat( internal_flags, scheme: description.scheme, number, - flags: description.flags, + flags: (flags & !O_CLOEXEC) as u32, })) } OpenResult::External(desc) => desc, @@ -196,59 +202,42 @@ pub fn openat( .read(token.token()) .add_file(FileDescriptor { description: new_description, - cloexec: false, + cloexec: flags as usize & O_CLOEXEC == O_CLOEXEC, }) .ok_or(Error::new(EMFILE)) } -/// rmdir syscall -pub fn rmdir(raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> { - let (scheme_ns, caller_ctx) = { - let ctx = context::current(); - let cx = &ctx.read(token.token()); - (cx.ens, cx.caller_ctx()) - }; +/// Unlinkat syscall +pub fn unlinkat( + fh: FileHandle, + raw_path: UserSliceRo, + flags: usize, + euid: u32, + egid: u32, + token: &mut CleanLockToken, +) -> Result<()> { + let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?; + let pipe = context::current() + .read(token.token()) + .get_file(fh) + .ok_or(Error::new(EBADF))?; + + let description = pipe.description.read(); + + let scheme = scheme::schemes(token.token()) + .get(description.scheme) + .ok_or(Error::new(EBADF))? + .clone(); + + let caller_ctx = context::current() + .read(token.token()) + .caller_ctx() + .filter_uid_gid(euid, egid); /* let mut path_buf = BorrowedHtBuf::head()?; let path = path_buf.use_for_string(raw_path)?; */ - let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?; - let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?; - let (scheme_name, reference) = path.as_parts().ok_or(Error::new(EINVAL))?; - - let scheme = { - let schemes = scheme::schemes(token.token()); - let (_scheme_id, scheme) = schemes - .get_name(scheme_ns, scheme_name.as_ref()) - .ok_or(Error::new(ENODEV))?; - scheme.clone() - }; - scheme.rmdir(reference.as_ref(), caller_ctx, token) -} - -/// Unlink syscall -pub fn unlink(raw_path: UserSliceRo, token: &mut CleanLockToken) -> Result<()> { - let (scheme_ns, caller_ctx) = { - let ctx = context::current(); - let cx = &ctx.read(token.token()); - (cx.ens, cx.caller_ctx()) - }; - /* - let mut path_buf = BorrowedHtBuf::head()?; - let path = path_buf.use_for_string(raw_path)?; - */ - let path_buf = copy_path_to_buf(raw_path, PATH_MAX)?; - let path = RedoxPath::from_absolute(&path_buf).ok_or(Error::new(EINVAL))?; - let (scheme_name, reference) = path.as_parts().ok_or(Error::new(EINVAL))?; - - let scheme = { - let schemes = scheme::schemes(token.token()); - let (_scheme_id, scheme) = schemes - .get_name(scheme_ns, scheme_name.as_ref()) - .ok_or(Error::new(ENODEV))?; - scheme.clone() - }; - scheme.unlink(reference.as_ref(), caller_ctx, token) + scheme.unlinkat(description.number, &path_buf, flags, caller_ctx, token) } /// Close syscall diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 73b63778a7..a23a8e62f4 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -61,6 +61,7 @@ pub fn syscall( d: usize, e: usize, f: usize, + g: usize, token: &mut CleanLockToken, ) -> usize { #[inline(always)] @@ -71,6 +72,7 @@ pub fn syscall( d: usize, e: usize, f: usize, + g: usize, token: &mut CleanLockToken, ) -> Result { let fd = FileHandle::from(b); @@ -205,11 +207,24 @@ pub fn syscall( UserSlice::ro(f, (e & 0xff) * 8)?, token, ), - SYS_OPEN => open(UserSlice::ro(b, c)?, d, token).map(FileHandle::into), - SYS_OPENAT => openat(fd, UserSlice::ro(c, d)?, e, f as _, token).map(FileHandle::into), - SYS_RMDIR => rmdir(UserSlice::ro(b, c)?, token).map(|()| 0), - SYS_UNLINK => unlink(UserSlice::ro(b, c)?, token).map(|()| 0), + SYS_OPENAT => { + openat(fd, UserSlice::ro(c, d)?, e, f as _, 0, 0, token).map(FileHandle::into) + } + SYS_OPENAT_WITH_FILTER => openat( + fd, + UserSlice::ro(c, d)?, + e, + (e & syscall::O_FCNTL_MASK) as _, + f as _, + g as _, + token, + ) + .map(FileHandle::into), + SYS_UNLINKAT => unlinkat(fd, UserSlice::ro(c, d)?, e, 0, 0, token).map(|()| 0), + SYS_UNLINKAT_WITH_FILTER => { + unlinkat(fd, UserSlice::ro(c, d)?, e, f as _, g as _, token).map(|()| 0) + } SYS_YIELD => sched_yield(token).map(|()| 0), SYS_NANOSLEEP => nanosleep( UserSlice::ro(b, core::mem::size_of::())?, @@ -239,11 +254,11 @@ pub fn syscall( PercpuBlock::current().inside_syscall.set(true); - debug_start([a, b, c, d, e, f], token); + debug_start([a, b, c, d, e, f, g], token); - let result = inner(a, b, c, d, e, f, token); + let result = inner(a, b, c, d, e, f, g, token); - debug_end([a, b, c, d, e, f], result, token); + debug_end([a, b, c, d, e, f, g], result, token); let percpu = PercpuBlock::current(); percpu.inside_syscall.set(false);