Pass si_uid and si_pid to kill signals.

This commit is contained in:
4lDO2
2024-08-02 16:04:41 +02:00
parent 7def7ce6e3
commit fcb2e2be3a
2 changed files with 53 additions and 12 deletions
+10 -1
View File
@@ -13,7 +13,7 @@ use crate::{
scheme::{self, FileHandle, KernelScheme},
syscall::{
self,
data::{GrantDesc, Map, PtraceEvent, SetSighandlerData, Stat},
data::{GrantDesc, Map, PtraceEvent, SenderInfo, SetSighandlerData, Stat},
error::*,
flag::*,
usercopy::{UserSliceRo, UserSliceWo},
@@ -1466,6 +1466,14 @@ impl ContextHandle {
Ok(mem::size_of::<usize>())
}
ContextHandle::Signal => {
let me = {
let p = process::current()?;
let p = p.read();
SenderInfo {
pid: p.pid.get().try_into().unwrap_or(0),
ruid: p.ruid,
}
};
let sig = buf.read_u32()?;
let mut killed_self = false;
crate::syscall::process::send_signal(
@@ -1474,6 +1482,7 @@ impl ContextHandle {
KillMode::Idempotent,
false,
&mut killed_self,
me,
)?;
if killed_self {
Err(Error::new(EINTR))
+43 -11
View File
@@ -1,7 +1,9 @@
use alloc::{collections::VecDeque, sync::Arc, vec::Vec};
use core::{mem, num::NonZeroUsize, sync::atomic::Ordering};
use spinning_top::RwSpinlock;
use syscall::{sig_bit, RtSigInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU};
use syscall::{
sig_bit, RtSigInfo, SenderInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU,
};
use rmm::Arch;
use spin::RwLock;
@@ -87,10 +89,12 @@ pub fn exit(status: usize) -> ! {
Some(ptrace_event!(PTRACE_STOP_EXIT, status)),
);
let current_pid;
let current_ruid;
{
let current_context = context::current();
let current_process = process::current().expect("no active process during exit syscall");
let current_pid = current_process.read().pid;
current_pid = current_process.read().pid;
let threads = core::mem::take(&mut current_process.write().threads);
@@ -107,6 +111,7 @@ pub fn exit(status: usize) -> ! {
// PGID and PPID must be grabbed after close, as context switches could change PGID or PPID if parent exits
let (pgid, ppid) = {
let process = current_process.read();
current_ruid = process.ruid;
(process.pgid, process.ppid)
};
if let Some(parent) = process::PROCESSES.read().get(&ppid).map(Arc::clone) {
@@ -116,6 +121,10 @@ pub fn exit(status: usize) -> ! {
KillMode::Idempotent,
true,
&mut false,
SenderInfo {
pid: current_pid.get().try_into().unwrap_or(0),
ruid: current_ruid,
},
);
}
@@ -194,12 +203,14 @@ pub fn send_signal(
mode: KillMode,
is_sigchld_to_parent: bool,
killed_self: &mut bool,
sender: SenderInfo,
) -> Result<()> {
if sig > 64 {
return Err(Error::new(EINVAL));
}
let sig_group = (sig - 1) / 32;
let sig_idx = sig - 1;
let (context_lock, process_lock) = match target {
KillTarget::Thread(ref c) => (Arc::clone(&c), Arc::clone(&c.read().process)),
@@ -227,6 +238,7 @@ pub fn send_signal(
pgid: ProcessId,
},
FullQ,
Invalid,
}
let result = (|| {
@@ -332,6 +344,8 @@ pub fn send_signal(
{
match target {
KillTarget::Thread(_) => {
tctl.sender_infos[sig_idx].store(sender.raw(), Ordering::Relaxed);
let _was_new = tctl.word[sig_group].fetch_or(sig_bit(sig), Ordering::Relaxed);
if (tctl.word[sig_group].load(Ordering::Relaxed) >> 32) & sig_bit(sig) != 0 {
context_guard.unblock();
@@ -340,9 +354,12 @@ pub fn send_signal(
}
KillTarget::Process(proc) => {
match mode {
KillMode::Queued(arg) if sig_group == 1 => {
let rtidx = sig - 33;
//log::info!("QUEUEING {arg} RTIDX {rtidx}");
KillMode::Queued(arg) => {
if sig_group != 1 || sig_idx < 32 || sig_idx >= 64 {
return SendResult::Invalid;
}
let rtidx = sig_idx - 32;
//log::info!("QUEUEING {arg:?} RTIDX {rtidx}");
if rtidx >= sigst.rtqs.len() {
sigst.rtqs.resize_with(rtidx + 1, VecDeque::new);
}
@@ -355,7 +372,12 @@ pub fn send_signal(
rtq.push_back(arg);
}
_ => (),
KillMode::Idempotent => {
if sig_group != 0 {
return SendResult::Invalid;
}
pctl.sender_infos[sig_idx].store(sender.raw(), Ordering::Relaxed);
}
}
pctl.pending.fetch_or(sig_bit(sig), Ordering::Release);
@@ -389,6 +411,7 @@ pub fn send_signal(
match result {
SendResult::Succeeded => (),
SendResult::FullQ => return Err(Error::new(EAGAIN)),
SendResult::Invalid => return Err(Error::new(EINVAL)),
SendResult::SucceededSigchld {
ppid,
pgid,
@@ -413,6 +436,7 @@ pub fn send_signal(
mode,
true,
killed_self,
sender,
)?;
}
SendResult::SucceededSigcont { ppid, pgid } => {
@@ -444,13 +468,17 @@ pub enum KillMode {
}
pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result<usize> {
let (ruid, euid, current_pgid) = {
let (current_ruid, current_euid, current_pgid, current_pid) = {
let process_lock = process::current()?;
let process = process_lock.read();
(process.ruid, process.euid, process.pgid)
(process.ruid, process.euid, process.pgid, process.pid)
};
let sender = SenderInfo {
pid: current_pid.get().try_into().unwrap_or(0),
ruid: current_ruid,
};
if euid == 0 && pid.get() == 1 {
if current_euid == 0 && pid.get() == 1 {
match sig {
SIGTERM => unsafe { crate::stop::kreset() },
SIGKILL => unsafe { crate::stop::kstop() },
@@ -463,8 +491,9 @@ pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result<usize> {
let mut killed_self = false;
// Non-root users cannot kill arbitrarily.
let can_send =
|proc_info: &ProcessInfo| euid == 0 || euid == proc_info.ruid || ruid == proc_info.ruid;
let can_send = |proc_info: &ProcessInfo| {
current_euid == 0 || current_euid == proc_info.ruid || current_ruid == proc_info.ruid
};
{
let processes = process::PROCESSES.read();
@@ -481,6 +510,7 @@ pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result<usize> {
mode,
false,
&mut killed_self,
sender,
)?;
}
}
@@ -499,6 +529,7 @@ pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result<usize> {
mode,
false,
&mut killed_self,
sender,
)?;
}
}
@@ -524,6 +555,7 @@ pub fn kill(pid: ProcessId, sig: usize, mode: KillMode) -> Result<usize> {
mode,
false,
&mut killed_self,
sender,
)?;
}
}