kernel: Handle some invalid arguments in signal syscalls

This commit is contained in:
K. Lange 2022-08-18 15:08:56 +09:00
parent da7651cec6
commit ab4c474768
2 changed files with 13 additions and 11 deletions

View File

@ -104,6 +104,8 @@ static void maybe_restart_system_call(struct regs * r, int signum) {
}
}
#define PENDING (this_core->current_process->pending_signals & ((~this_core->current_process->blocked_signals) | (1 << SIGSTOP) | (1 << SIGKILL)))
/**
* @brief Examine the pending signal and perform an appropriate action.
*
@ -157,7 +159,7 @@ int handle_signal(process_t * proc, int signum, struct regs *r) {
do {
switch_task(0);
} while (!(this_core->current_process->pending_signals & ~this_core->current_process->blocked_signals));
} while (!PENDING);
return 0; /* Return and handle another */
} else if (dowhat == SIG_DISP_Cont) {
@ -182,7 +184,7 @@ _ignore_signal:
maybe_restart_system_call(r, signum);
return !(this_core->current_process->pending_signals & ~this_core->current_process->blocked_signals);
return !PENDING;
}
/**
@ -234,7 +236,7 @@ int send_signal(pid_t process, int signal, int force_root) {
return 0;
}
if (receiver->blocked_signals & (1 << signal)) {
if ((receiver->blocked_signals & (1 << signal)) && signal != SIGKILL && signal != SIGSTOP) {
spin_lock(sig_lock);
receiver->pending_signals |= (1 << signal);
spin_unlock(sig_lock);
@ -321,7 +323,7 @@ void process_check_signals(struct regs * r) {
spin_lock(sig_lock);
if (this_core->current_process && !(this_core->current_process->flags & PROC_FLAG_FINISHED)) {
/* Set an pending signals that were previously blocked */
sigset_t active_signals = this_core->current_process->pending_signals & ~this_core->current_process->blocked_signals;
sigset_t active_signals = PENDING;
int signal = 0;
while (active_signals && signal <= NUMSIGNALS) {
@ -351,7 +353,7 @@ void process_check_signals(struct regs * r) {
*/
void return_from_signal_handler(struct regs *r) {
int signum = arch_return_from_signal_handler(r);
if (this_core->current_process->pending_signals & ~this_core->current_process->blocked_signals) {
if (PENDING) {
process_check_signals(r);
}
maybe_restart_system_call(r,signum);

View File

@ -946,9 +946,8 @@ long sys_pipe(int pipes[2]) {
}
long sys_signal(long signum, uintptr_t handler) {
if (signum > NUMSIGNALS) {
return -EINVAL;
}
if (signum > NUMSIGNALS) return -EINVAL;
if (signum == SIGKILL || signum == SIGSTOP) return -EINVAL;
uintptr_t old = this_core->current_process->signals[signum].handler;
this_core->current_process->signals[signum].handler = handler;
this_core->current_process->signals[signum].flags = SA_RESTART;
@ -957,9 +956,10 @@ long sys_signal(long signum, uintptr_t handler) {
long sys_sigaction(int signum, struct sigaction *act, struct sigaction *oldact) {
if (act) PTRCHECK(act,sizeof(struct sigaction),0);
if (oldact) PTRCHECK(oldact,sizeof(struct sigaction),0);
if (oldact) PTRCHECK(oldact,sizeof(struct sigaction),MMU_PTR_WRITE);
if (signum > NUMSIGNALS) return -EINVAL;
if (signum == SIGKILL || signum == SIGSTOP) return -EINVAL;
if (oldact) {
oldact->sa_handler = (_sig_func_ptr)this_core->current_process->signals[signum].handler;
@ -977,14 +977,14 @@ long sys_sigaction(int signum, struct sigaction *act, struct sigaction *oldact)
}
long sys_sigpending(sigset_t * set) {
PTRCHECK(set,sizeof(sigset_t),0);
PTRCHECK(set,sizeof(sigset_t),MMU_PTR_WRITE);
*set = this_core->current_process->pending_signals;
return 0;
}
long sys_sigprocmask(int how, sigset_t *restrict set, sigset_t * restrict oset) {
if (oset) {
PTRCHECK(oset,sizeof(sigset_t),0);
PTRCHECK(oset,sizeof(sigset_t),MMU_PTR_WRITE);
*oset = this_core->current_process->blocked_signals;
}