Patch add abort func (#120)

* 对于除了sigkill以外的信号,也加入队列

* bugfix:libc中,注册信号处理函数时,总是注册sigkill的问题

* 增加getpid系统调用

* 增加了raise、kill、abort
This commit is contained in:
login 2022-12-19 15:03:44 +08:00 committed by GitHub
parent 47f0d12a1f
commit c588d6f77f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 155 additions and 52 deletions

View File

@ -64,6 +64,7 @@ pub static DEFAULT_SIGACTION_IGNORE: sigaction = sigaction {
pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 { pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
let pid: pid_t = regs.r8 as pid_t; let pid: pid_t = regs.r8 as pid_t;
let sig: SignalNumber = SignalNumber::from(regs.r9 as i32); let sig: SignalNumber = SignalNumber::from(regs.r9 as i32);
if sig == SignalNumber::INVALID { if sig == SignalNumber::INVALID {
// 传入的signal数值不合法 // 传入的signal数值不合法
kwarn!("Not a valid signal number"); kwarn!("Not a valid signal number");
@ -86,29 +87,43 @@ pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
}; };
compiler_fence(core::sync::atomic::Ordering::SeqCst); compiler_fence(core::sync::atomic::Ordering::SeqCst);
let retval = signal_kill_something_info(sig, Some(&mut info), pid) as u64; let retval = signal_kill_something_info(sig, Some(&mut info), pid);
let x;
if retval.is_ok() {
x = retval.unwrap();
} else {
x = retval.unwrap_err();
}
compiler_fence(core::sync::atomic::Ordering::SeqCst); compiler_fence(core::sync::atomic::Ordering::SeqCst);
return retval;
return x as u64;
} }
/// 通过kill的方式向目标进程发送信号 /// 通过kill的方式向目标进程发送信号
/// @param sig 要发送的信号 /// @param sig 要发送的信号
/// @param info 要发送的信息 /// @param info 要发送的信息
/// @param pid 进程id目前只支持pid>0) /// @param pid 进程id目前只支持pid>0)
fn signal_kill_something_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 { fn signal_kill_something_info(
sig: SignalNumber,
info: Option<&mut siginfo>,
pid: pid_t,
) -> Result<i32, i32> {
// 暂时不支持特殊的kill操作 // 暂时不支持特殊的kill操作
if pid <= 0 { if pid <= 0 {
kwarn!("Kill operation not support: pid={}", pid); kwarn!("Kill operation not support: pid={}", pid);
return -(ENOTSUP as i32); return Err(-(ENOTSUP as i32));
} }
// kill单个进程 // kill单个进程
return signal_kill_proc_info(sig, info, pid); return signal_kill_proc_info(sig, info, pid);
} }
fn signal_kill_proc_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 { fn signal_kill_proc_info(
let mut retval: i32 = -(ESRCH as i32); sig: SignalNumber,
info: Option<&mut siginfo>,
pid: pid_t,
) -> Result<i32, i32> {
let mut retval = Err(-(ESRCH as i32));
// step1: 当进程管理模块拥有pcblist_lock之后对其加锁 // step1: 当进程管理模块拥有pcblist_lock之后对其加锁
@ -147,16 +162,16 @@ fn signal_send_sig_info(
sig: SignalNumber, sig: SignalNumber,
info: Option<&mut siginfo>, info: Option<&mut siginfo>,
target_pcb: &mut process_control_block, target_pcb: &mut process_control_block,
) -> i32 { ) -> Result<i32, i32> {
// kdebug!("signal_send_sig_info"); // kdebug!("signal_send_sig_info");
// 检查sig是否符合要求如果不符合要求则退出。 // 检查sig是否符合要求如果不符合要求则退出。
if !verify_signal(sig) { if !verify_signal(sig) {
return -(EINVAL as i32); return Err(-(EINVAL as i32));
} }
// 信号符合要求,可以发送 // 信号符合要求,可以发送
let mut retval = -(ESRCH as i32); let mut retval = Err(-(ESRCH as i32));
let mut flags: u64 = 0; let mut flags: u64 = 0;
// 如果上锁成功,则发送信号 // 如果上锁成功,则发送信号
if !lock_process_sighand(target_pcb, &mut flags).is_none() { if !lock_process_sighand(target_pcb, &mut flags).is_none() {
@ -214,7 +229,7 @@ fn send_signal_locked(
info: Option<&mut siginfo>, info: Option<&mut siginfo>,
pcb: &mut process_control_block, pcb: &mut process_control_block,
pt: PidType, pt: PidType,
) -> i32 { ) -> Result<i32, i32> {
// 是否强制发送信号 // 是否强制发送信号
let mut force_send = false; let mut force_send = false;
// signal的信息为空 // signal的信息为空
@ -240,13 +255,12 @@ fn send_signal_locked(
/// @return i32 错误码 /// @return i32 错误码
fn __send_signal_locked( fn __send_signal_locked(
sig: SignalNumber, sig: SignalNumber,
_info: Option<&mut siginfo>, info: Option<&mut siginfo>,
pcb: &mut process_control_block, pcb: &mut process_control_block,
pt: PidType, pt: PidType,
_force_send: bool, _force_send: bool,
) -> i32 { ) -> Result<i32, i32> {
// kdebug!("__send_signal_locked"); // kdebug!("__send_signal_locked");
let mut retval = 0;
// 判断该进入该函数时,是否已经持有了锁 // 判断该进入该函数时,是否已经持有了锁
assert!(spin_is_locked(unsafe { &(*pcb.sighand).siglock })); assert!(spin_is_locked(unsafe { &(*pcb.sighand).siglock }));
@ -257,11 +271,26 @@ fn __send_signal_locked(
if sig == SignalNumber::SIGKILL || (pcb.flags & (PF_KTHREAD as u64)) != 0 { if sig == SignalNumber::SIGKILL || (pcb.flags & (PF_KTHREAD as u64)) != 0 {
complete_signal(sig, pcb, pt); complete_signal(sig, pcb, pt);
} else { } else {
// todo: 如果是其他信号则加入到sigqueue内然后complete_signal // 如果是其他信号则加入到sigqueue内然后complete_signal
retval = -(ENOTSUP as i32); let mut q: siginfo;
match info {
Some(x) => {
// 已经显式指定了siginfo则直接使用它。
q = x.clone();
}
None => {
// 不需要显示指定siginfo因此设置为默认值
q = siginfo::new(sig, 0, si_code_val::SI_USER);
q._sinfo.data._sifields._kill._pid = current_pcb().pid;
}
}
let sq: &mut SigQueue = SigQueue::from_c_void(current_pcb().sig_pending.sigqueue);
sq.q.push(q);
complete_signal(sig, pcb, pt);
} }
compiler_fence(core::sync::atomic::Ordering::SeqCst); compiler_fence(core::sync::atomic::Ordering::SeqCst);
return retval; return Ok(0);
} }
/// @brief 将信号添加到目标进程的sig_pending。在引入进程组后本函数还将负责把信号传递给整个进程组。 /// @brief 将信号添加到目标进程的sig_pending。在引入进程组后本函数还将负责把信号传递给整个进程组。
@ -407,8 +436,7 @@ pub extern "C" fn do_signal(regs: &mut pt_regs) {
// 做完上面的检查后,开中断 // 做完上面的检查后,开中断
sti(); sti();
// return;
// kdebug!("do_signal");
let oldset = current_pcb().sig_blocked; let oldset = current_pcb().sig_blocked;
loop { loop {
let (sig_number, info, ka) = get_signal_to_deliver(regs.clone()); let (sig_number, info, ka) = get_signal_to_deliver(regs.clone());
@ -790,7 +818,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
} }
let mask: sigset_t = unsafe { (*act).sa_mask }; let mask: sigset_t = unsafe { (*act).sa_mask };
let _input_sah = unsafe { (*act).sa_handler as u64 }; let _input_sah = unsafe { (*act).sa_handler as u64 };
// kdebug!("_input_sah={}", _input_sah);
match _input_sah { match _input_sah {
USER_SIG_DFL | USER_SIG_IGN => { USER_SIG_DFL | USER_SIG_IGN => {
if _input_sah == USER_SIG_DFL { if _input_sah == USER_SIG_DFL {
@ -818,6 +846,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
}; };
} }
} }
// kdebug!("new_ka={:?}", new_ka);
// 如果用户手动给了sa_restorer那么就置位SA_FLAG_RESTORER否则报错。用户必须手动指定restorer // 如果用户手动给了sa_restorer那么就置位SA_FLAG_RESTORER否则报错。用户必须手动指定restorer
if new_ka.sa_restorer != NULL as u64 { if new_ka.sa_restorer != NULL as u64 {
new_ka.sa_flags |= SA_FLAG_RESTORER; new_ka.sa_flags |= SA_FLAG_RESTORER;
@ -875,6 +904,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
(*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void; (*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void;
} }
} }
return retval as u64; return retval as u64;
} }
@ -946,8 +976,7 @@ fn do_sigaction(
let mut mask: sigset_t = 0; let mut mask: sigset_t = 0;
sigset_clear(&mut mask); sigset_clear(&mut mask);
sigset_add(&mut mask, sig); sigset_add(&mut mask, sig);
let sq = pcb.sig_pending.sigqueue as *mut SigQueue; let sq: &mut SigQueue = SigQueue::from_c_void(pcb.sig_pending.sigqueue);
let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
sq.flush_by_mask(&mask); sq.flush_by_mask(&mask);
// todo: 当有了多个线程后在这里进行操作把每个线程的sigqueue都进行刷新 // todo: 当有了多个线程后在这里进行操作把每个线程的sigqueue都进行刷新
@ -966,11 +995,6 @@ pub fn sigmask(sig: SignalNumber) -> u64 {
#[no_mangle] #[no_mangle]
pub extern "C" fn sys_rt_sigreturn(regs: &mut pt_regs) -> u64 { pub extern "C" fn sys_rt_sigreturn(regs: &mut pt_regs) -> u64 {
// kdebug!(
// "sigreturn, pid={}, regs.rsp=0x{:018x}",
// current_pcb().pid,
// regs.rsp
// );
let frame = regs.rsp as usize as *mut sigframe; let frame = regs.rsp as usize as *mut sigframe;
// 如果当前的rsp不来自用户态则认为产生了错误或被SROP攻击 // 如果当前的rsp不来自用户态则认为产生了错误或被SROP攻击

View File

@ -93,9 +93,9 @@ pub const SA_ALL_FLAGS: u64 = SA_FLAG_IGN | SA_FLAG_DFL | SA_FLAG_RESTORER | SA_
// ============ sigaction结构体中的的sa_flags的可选值 end =========== // ============ sigaction结构体中的的sa_flags的可选值 end ===========
/// 用户态程序传入的SIG_DFL的值 /// 用户态程序传入的SIG_DFL的值
pub const USER_SIG_DFL: u64 = 1u64 << 0; pub const USER_SIG_DFL: u64 = 0;
/// 用户态程序传入的SIG_IGN的值 /// 用户态程序传入的SIG_IGN的值
pub const USER_SIG_IGN: u64 = 1u64 << 1; pub const USER_SIG_IGN: u64 = 1;
/** /**
* @brief * @brief
@ -544,6 +544,13 @@ impl SigQueue {
drop(x) drop(x)
} }
} }
/// @brief 从C的void*指针转换为static生命周期的可变引用
pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue{
let sq = p as *mut SigQueue;
let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
return sq;
}
} }
impl Default for SigQueue { impl Default for SigQueue {
@ -587,7 +594,7 @@ pub fn sigset_delmask(set: &mut sigset_t, mask: u64) {
/// @brief 判断两个sigset是否相等 /// @brief 判断两个sigset是否相等
#[inline] #[inline]
pub fn sigset_equal(a: &sigset_t, b: &sigset_t) -> bool { pub fn sigset_equal(a: &sigset_t, b: &sigset_t) -> bool {
if _NSIG_U64_CNT == 1{ if _NSIG_U64_CNT == 1 {
return *a == *b; return *a == *b;
} }
return false; return false;

View File

@ -1,3 +1,5 @@
use crate::{include::bindings::bindings::pt_regs, arch::x86_64::asm::current::current_pcb};
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
#[repr(u8)] #[repr(u8)]
@ -15,4 +17,12 @@ impl PartialEq for PidType {
fn eq(&self, other: &PidType) -> bool { fn eq(&self, other: &PidType) -> bool {
*self as u8 == *other as u8 *self as u8 == *other as u8
} }
}
/**
* @brief pid
*/
#[no_mangle]
pub extern "C" fn sys_getpid(_regs: &pt_regs)->u64{
return current_pcb().pid as u64;
} }

View File

@ -22,6 +22,7 @@ extern uint64_t sys_unlink_at(struct pt_regs *regs);
extern uint64_t sys_kill(struct pt_regs *regs); extern uint64_t sys_kill(struct pt_regs *regs);
extern uint64_t sys_sigaction(struct pt_regs * regs); extern uint64_t sys_sigaction(struct pt_regs * regs);
extern uint64_t sys_rt_sigreturn(struct pt_regs * regs); extern uint64_t sys_rt_sigreturn(struct pt_regs * regs);
extern uint64_t sys_getpid(struct pt_regs * regs);
/** /**
* @brief * @brief
@ -590,6 +591,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
[23] = sys_kill, [23] = sys_kill,
[24] = sys_sigaction, [24] = sys_sigaction,
[25] = sys_rt_sigreturn, [25] = sys_rt_sigreturn,
[26 ... 254] = system_call_not_exists, [26] = sys_getpid,
[27 ... 254] = system_call_not_exists,
[255] = sys_ahci_end_req, [255] = sys_ahci_end_req,
}; };

View File

@ -37,5 +37,6 @@
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号) #define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
#define SYS_SIGACTION 24 // 设置进程的信号处理动作 #define SYS_SIGACTION 24 // 设置进程的信号处理动作
#define SYS_RT_SIGRETURN 25 // 从信号处理函数返回 #define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
#define SYS_GETPID 26 // 获取当前进程的pid进程标识符
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用 #define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用

View File

@ -529,7 +529,7 @@ int shell_cmd_kill(int argc, char **argv)
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
} }
retval = syscall_invoke(SYS_KILL, atoi(argv[1]), SIGKILL, 0, 0, 0, 0, 0, 0); retval = kill(atoi(argv[1]), SIGKILL);
out:; out:;
free(argv); free(argv);
return retval; return retval;

View File

@ -40,7 +40,10 @@
#define SIGRTMIN 32 #define SIGRTMIN 32
#define SIGRTMAX MAX_SIG_NUM #define SIGRTMAX MAX_SIG_NUM
typedef void (*__sighandler_t) (int); typedef void (*__sighandler_t)(int);
#define SIG_DFL ((__sighandler_t)0) /* Default action. */
#define SIG_IGN ((__sighandler_t)1) /* Ignore signal. */
// 注意该结构体最大16字节 // 注意该结构体最大16字节
union __sifields { union __sifields {
@ -86,4 +89,6 @@ struct sigaction
}; };
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
int signal(int signum, __sighandler_t handler); int signal(int signum, __sighandler_t handler);
int raise(int sig);
int kill(pid_t, int sig);

View File

@ -14,10 +14,10 @@ void __libc_sa_restorer()
/** /**
* @brief * @brief
* *
* @param signum * @param signum
* @param handler * @param handler
* @return int * @return int
*/ */
int signal(int signum, __sighandler_t handler) int signal(int signum, __sighandler_t handler)
{ {
@ -27,12 +27,12 @@ int signal(int signum, __sighandler_t handler)
sa.sa_restorer = &__libc_sa_restorer; sa.sa_restorer = &__libc_sa_restorer;
// printf("handler address: %#018lx\n", handler); // printf("handler address: %#018lx\n", handler);
// printf("restorer address: %#018lx\n", &__libc_sa_restorer); // printf("restorer address: %#018lx\n", &__libc_sa_restorer);
sigaction(SIGKILL, &sa, NULL); sigaction(signum, &sa, NULL);
} }
/** /**
* @brief * @brief
* *
* @param signum * @param signum
* @param act NULL * @param act NULL
* @param oldact NULL * @param oldact NULL
@ -41,4 +41,27 @@ int signal(int signum, __sighandler_t handler)
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
{ {
return syscall_invoke(SYS_SIGACTION, (uint64_t)signum, (uint64_t)act, (uint64_t)oldact, 0, 0, 0, 0, 0); return syscall_invoke(SYS_SIGACTION, (uint64_t)signum, (uint64_t)act, (uint64_t)oldact, 0, 0, 0, 0, 0);
}
/**
* @brief
*
* @param sig signal number
* @return int
*/
int raise(int sig)
{
return kill(getpid(), sig);
}
/**
* @brief
*
* @param pid
* @param sig signal number
* @return int
*/
int kill(pid_t pid, int sig)
{
syscall_invoke(SYS_KILL, pid, sig, 0, 0, 0, 0, 0, 0);
} }

View File

@ -1,7 +1,8 @@
#include <libc/src/unistd.h>
#include <libc/src/stdlib.h>
#include <libc/src/ctype.h> #include <libc/src/ctype.h>
#include <libc/src/stdlib.h>
#include <libc/src/unistd.h>
#include <libsystem/syscall.h> #include <libsystem/syscall.h>
#include <libc/src/include/signal.h>
int abs(int i) int abs(int i)
{ {
@ -54,4 +55,15 @@ int atoi(const char *str)
void exit(int status) void exit(int status)
{ {
syscall_invoke(SYS_EXIT, status, 0, 0, 0, 0, 0, 0, 0); syscall_invoke(SYS_EXIT, status, 0, 0, 0, 0, 0, 0, 0);
}
/**
* @brief SIGABRT退
*
*/
void abort()
{
// step1设置SIGABRT的处理函数为SIG_DFL
signal(SIGABRT, SIG_DFL);
raise(SIGABRT);
} }

View File

@ -39,4 +39,10 @@ int atoi(const char * str);
* *
* @param status * @param status
*/ */
void exit(int status); void exit(int status);
/**
* @brief SIGABRT退
*
*/
void abort();

View File

@ -1,10 +1,10 @@
#include <libc/src/errno.h>
#include <libc/src/fcntl.h>
#include <libc/src/stddef.h>
#include <libc/src/stdio.h>
#include <libc/src/string.h>
#include <libc/src/unistd.h> #include <libc/src/unistd.h>
#include <libsystem/syscall.h> #include <libsystem/syscall.h>
#include <libc/src/errno.h>
#include <libc/src/stdio.h>
#include <libc/src/stddef.h>
#include <libc/src/string.h>
#include <libc/src/fcntl.h>
/** /**
* @brief * @brief
@ -163,11 +163,11 @@ int rmdir(const char *path)
/** /**
* @brief * @brief
* *
* @param path * @param path
* @return int * @return int
*/ */
int rm(const char * path) int rm(const char *path)
{ {
return syscall_invoke(SYS_UNLINK_AT, 0, (uint64_t)path, 0, 0, 0, 0, 0, 0); return syscall_invoke(SYS_UNLINK_AT, 0, (uint64_t)path, 0, 0, 0, 0, 0, 0);
} }
@ -193,4 +193,14 @@ void swab(void *restrict src, void *restrict dest, ssize_t nbytes)
_src += transfer; _src += transfer;
_dest += transfer; _dest += transfer;
} }
}
/**
* @brief pid
*
* @return pid_t pid
*/
pid_t getpid(void)
{
syscall_invoke(SYS_GETPID, 0, 0, 0, 0, 0, 0, 0, 0);
} }

View File

@ -114,4 +114,6 @@ int rm(const char * path);
* @param dest * @param dest
* @param nbytes * @param nbytes
*/ */
void swab(void *restrict src, void *restrict dest, ssize_t nbytes); void swab(void *restrict src, void *restrict dest, ssize_t nbytes);
pid_t getpid(void);

View File

@ -31,6 +31,7 @@
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号) #define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
#define SYS_SIGACTION 24 // 设置进程的信号处理动作 #define SYS_SIGACTION 24 // 设置进程的信号处理动作
#define SYS_RT_SIGRETURN 25 // 从信号处理函数返回 #define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
#define SYS_GETPID 26 // 获取当前进程的pid进程标识符
/** /**
* @brief * @brief