Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions kernel/src/arch/x86_64/ipc/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
mm::MemoryManagementArch,
process::ProcessManager,
sched::{schedule, SchedMode},
syscall::{user_access::UserBufferWriter, Syscall},
syscall::user_access::UserBufferWriter,
};

/// 信号处理的栈的栈指针的最小对齐数量
Expand Down Expand Up @@ -556,17 +556,23 @@ impl SignalArch for X86_64SignalArch {
// 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() {
error!("rsp doesn't from user level");
let _r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV)
.map_err(|e| e.to_posix_errno());
let _r = crate::ipc::kill::kill_process(
ProcessManager::current_pcb().pid(),
Signal::SIGSEGV,
)
.map_err(|e| e.to_posix_errno());
return trap_frame.rax;
}
let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
set_current_blocked(&mut sigmask);
// 从用户栈恢复sigcontext
if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
error!("unable to restore sigcontext");
let _r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV)
.map_err(|e| e.to_posix_errno());
let _r = crate::ipc::kill::kill_process(
ProcessManager::current_pcb().pid(),
Signal::SIGSEGV,
)
.map_err(|e| e.to_posix_errno());
// 如果这里返回 err 值的话会丢失上一个系统调用的返回值
}
// 由于系统调用的返回值会被系统调用模块被存放在rax寄存器,因此,为了还原原来的那个系统调用的返回值,我们需要在这里返回恢复后的rax的值
Expand Down Expand Up @@ -658,7 +664,7 @@ fn setup_frame(
ProcessManager::current_pcb().pid(),
sig as i32
);
let r = Syscall::kill_process(
let r = crate::ipc::kill::kill_process(
ProcessManager::current_pcb().pid(),
Signal::SIGSEGV,
);
Expand Down Expand Up @@ -698,7 +704,8 @@ fn setup_frame(
if r.is_err() {
// 如果地址区域位于内核空间,则直接报错
// todo: 生成一个sigsegv
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
let r =
crate::ipc::kill::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
if r.is_err() {
error!("In setup frame: generate SIGSEGV signal failed");
}
Expand All @@ -709,7 +716,10 @@ fn setup_frame(
// 将siginfo拷贝到用户栈
info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo })
.map_err(|e| -> SystemError {
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
let r = crate::ipc::kill::kill_process(
ProcessManager::current_pcb().pid(),
Signal::SIGSEGV,
);
if r.is_err() {
error!("In copy_siginfo_to_user: generate SIGSEGV signal failed");
}
Expand All @@ -723,7 +733,10 @@ fn setup_frame(
.context
.setup_sigcontext(oldset, trap_frame)
.map_err(|e: SystemError| -> SystemError {
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
let r = crate::ipc::kill::kill_process(
ProcessManager::current_pcb().pid(),
Signal::SIGSEGV,
);
if r.is_err() {
error!("In setup_sigcontext: generate SIGSEGV signal failed");
}
Expand Down
7 changes: 2 additions & 5 deletions kernel/src/driver/tty/tty_job_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ use crate::{
arch::ipc::signal::{SigSet, Signal},
mm::VirtAddr,
process::{process_group::Pgid, Pid, ProcessFlags, ProcessManager},
syscall::{
user_access::{UserBufferReader, UserBufferWriter},
Syscall,
},
syscall::user_access::{UserBufferReader, UserBufferWriter},
};

use super::tty_core::{TtyCore, TtyIoctlCmd};
Expand Down Expand Up @@ -59,7 +56,7 @@ impl TtyJobCtrlManager {
} else if ProcessManager::is_current_pgrp_orphaned() {
return Err(SystemError::EIO);
} else {
Syscall::kill_process_group(pgid, sig)?;
crate::ipc::kill::kill_process_group(pgid, sig)?;
ProcessManager::current_pcb()
.flags()
.insert(ProcessFlags::HAS_PENDING_SIGNAL);
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/driver/tty/tty_ldisc/ntty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
mm::VirtAddr,
net::event_poll::EPollEventType,
process::{ProcessFlags, ProcessManager},
syscall::{user_access::UserBufferWriter, Syscall},
syscall::user_access::UserBufferWriter,
};

use super::TtyLineDiscipline;
Expand Down Expand Up @@ -790,7 +790,7 @@ impl NTtyData {
let ctrl_info = tty.core().contorl_info_irqsave();
let pg = ctrl_info.pgid;
if let Some(pg) = pg {
let _ = Syscall::kill_process_group(pg, signal);
let _ = crate::ipc::kill::kill_process_group(pg, signal);
}

if !termios.local_mode.contains(LocalMode::NOFLSH) {
Expand Down
44 changes: 44 additions & 0 deletions kernel/src/ipc/kill.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::arch::ipc::signal::{SigCode, Signal};
use crate::ipc::signal_types::{SigInfo, SigType};
use crate::process::{process_group::Pgid, Pid, ProcessManager};
use core::sync::atomic::compiler_fence;
use system_error::SystemError;

/// ### 杀死一个进程
pub fn kill_process(pid: Pid, sig: Signal) -> Result<usize, SystemError> {
// 初始化signal info
let mut info = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(pid));
compiler_fence(core::sync::atomic::Ordering::SeqCst);

let ret = sig
.send_signal_info(Some(&mut info), pid)
.map(|x| x as usize);

compiler_fence(core::sync::atomic::Ordering::SeqCst);
ret
}

/// ### 杀死一个进程组
pub fn kill_process_group(pgid: Pgid, sig: Signal) -> Result<usize, SystemError> {
let pg = ProcessManager::find_process_group(pgid).ok_or(SystemError::ESRCH)?;
let inner = pg.process_group_inner.lock();
for pcb in inner.processes.values() {
kill_process(pcb.pid(), sig)?; // Call the new common function
}
Ok(0)
}

/// ### 杀死所有进程
/// - 该函数会杀死所有进程,除了当前进程和init进程
pub fn kill_all(sig: Signal) -> Result<usize, SystemError> {
let current_pid = ProcessManager::current_pcb().pid();
let all_processes = ProcessManager::get_all_processes();

for pid_val in all_processes {
if pid_val == current_pid || pid_val.data() == 1 {
continue;
}
kill_process(pid_val, sig)?; // Call the new common function
}
Ok(0)
}
1 change: 1 addition & 0 deletions kernel/src/ipc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod generic_signal;
pub mod kill;
pub mod pipe;
pub mod shm;
pub mod signal;
Expand Down
19 changes: 18 additions & 1 deletion kernel/src/ipc/shm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ use crate::{
syscall::user_access::{UserBufferReader, UserBufferWriter},
time::PosixTimeSpec,
};
use core::fmt;
use core::sync::atomic::{compiler_fence, Ordering};
use hashbrown::HashMap;
use ida::IdAllocator;
use log::info;
use num::ToPrimitive;
use system_error::SystemError;

pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None;

/// 用于创建新的私有IPC对象
Expand Down Expand Up @@ -104,6 +104,23 @@ impl From<usize> for ShmCtlCmd {
}
}

impl fmt::Display for ShmCtlCmd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ShmCtlCmd::IpcRmid => write!(f, "IPC_RMID"),
ShmCtlCmd::IpcSet => write!(f, "IPC_SET"),
ShmCtlCmd::IpcStat => write!(f, "IPC_STAT"),
ShmCtlCmd::IpcInfo => write!(f, "IPC_INFO"),
ShmCtlCmd::ShmLock => write!(f, "SHM_LOCK"),
ShmCtlCmd::ShmUnlock => write!(f, "SHM_UNLOCK"),
ShmCtlCmd::ShmStat => write!(f, "SHM_STAT"),
ShmCtlCmd::ShmInfo => write!(f, "SHM_INFO"),
ShmCtlCmd::ShmtStatAny => write!(f, "SHM_STAT_ANY"),
ShmCtlCmd::Default => write!(f, "DEFAULT (Invalid Cmd)"),
}
}
}

impl PartialEq for ShmCtlCmd {
fn eq(&self, other: &ShmCtlCmd) -> bool {
*self as usize == *other as usize
Expand Down
Loading