diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs index 842dfc67f9..57a3b69168 100644 --- a/src/scheme/sys/mod.rs +++ b/src/scheme/sys/mod.rs @@ -5,7 +5,7 @@ use ::syscall::{ dirent::{DirEntry, DirentBuf, DirentKind}, - EBADFD, EIO, EISDIR, ENOTDIR, + EBADFD, EINVAL, EIO, EISDIR, ENOTDIR, EPERM, }; use alloc::{collections::BTreeMap, vec::Vec}; use core::{ @@ -97,10 +97,21 @@ const FILES: &[(&'static str, Kind)] = &[ "update_time_offset", Wr(crate::time::sys_update_time_offset), ), + ( + "kstop", + Wr(|arg| unsafe { + match arg.trim_ascii() { + b"shutdown" => crate::stop::kstop(), + b"reset" => crate::stop::kreset(), + b"emergency_reset" => crate::stop::emergency_reset(), + _ => Err(Error::new(EINVAL)), + } + }), + ), ]; impl KernelScheme for SysScheme { - fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result { + fn kopen(&self, path: &str, _flags: usize, ctx: CallerCtx) -> Result { let path = path.trim_matches('/'); if path.is_empty() { @@ -116,6 +127,10 @@ impl KernelScheme for SysScheme { .find(|(entry_path, _)| *entry_path == path) .ok_or(Error::new(ENOENT))?; + if matches!(entry.1, Wr(_)) && ctx.uid != 0 { + return Err(Error::new(EPERM)); + } + let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); let data = match entry.1 { Rd(r) => Some(r()?), diff --git a/src/syscall/process.rs b/src/syscall/process.rs index ff25f182a3..7dbe4ff29e 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -490,14 +490,6 @@ pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result { ruid: current_ruid, }; - if current_euid == 0 && pid.get() == 1 { - match sig { - SIGTERM => unsafe { crate::stop::kreset() }, - SIGKILL => unsafe { crate::stop::kstop() }, - _ => return Ok(0), // error? - } - } - let mut found = 0; let mut sent = 0; let mut killed_self = false;