kernel: be more prudent with signal number bounds checking

This commit is contained in:
K. Lange 2023-04-12 17:22:56 +09:00
parent 25fc898671
commit 441f853bc3
2 changed files with 8 additions and 5 deletions

View File

@ -95,6 +95,7 @@ static char sig_defaults[] = {
* @param r Registers after restoration from signal return.
*/
static void maybe_restart_system_call(struct regs * r, int signum) {
if (signum < 0 || signum >= NUMSIGNALS) return;
if (this_core->current_process->interrupted_system_call && arch_syscall_number(r) == -ERESTARTSYS) {
if (sig_defaults[signum] == SIG_DISP_Cont || (this_core->current_process->signals[signum].flags & SA_RESTART)) {
arch_syscall_return(r, this_core->current_process->interrupted_system_call);
@ -211,7 +212,7 @@ int send_signal(pid_t process, int signal, int force_root) {
if (!force_root && receiver->user != this_core->current_process->user && this_core->current_process->user != USER_ROOT_UID &&
!(signal == SIGCONT && receiver->session == this_core->current_process->session)) return -EPERM;
if (receiver->flags & PROC_FLAG_IS_TASKLET) return -EPERM;
if (signal > NUMSIGNALS) return -EINVAL;
if (signal >= NUMSIGNALS || signal < 0) return -EINVAL;
if (receiver->flags & PROC_FLAG_FINISHED) return -ESRCH;
if (signal == 0) return 0;
@ -265,6 +266,8 @@ int group_send_signal(pid_t group, int signal, int force_root) {
int kill_self = 0;
int killed_something = 0;
if (signal < 0) return 0;
foreach(node, process_list) {
process_t * proc = node->value;
if (proc->group == proc->id && proc->job == group) {
@ -304,7 +307,7 @@ _tryagain:
sigset_t active_signals = PENDING;
int signal = 0;
while (active_signals && signal <= NUMSIGNALS) {
while (active_signals && signal < NUMSIGNALS) {
if (active_signals & 1) {
this_core->current_process->pending_signals &= ~shift_signal(signal);
spin_unlock(sig_lock);
@ -370,7 +373,7 @@ int signal_await(sigset_t awaited, int * sig) {
sigset_t maybe = awaited & this_core->current_process->pending_signals;
if (maybe) {
int signal = 0;
while (maybe && signal <= NUMSIGNALS) {
while (maybe && signal < NUMSIGNALS) {
if (maybe & 1) {
spin_lock(sig_lock);
this_core->current_process->pending_signals &= ~shift_signal(signal);

View File

@ -955,7 +955,7 @@ long sys_pipe(int pipes[2]) {
}
long sys_signal(long signum, uintptr_t handler) {
if (signum > NUMSIGNALS || signum < 0) return -EINVAL;
if (signum >= NUMSIGNALS || signum < 0) 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;
@ -967,7 +967,7 @@ 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),MMU_PTR_WRITE);
if (signum > NUMSIGNALS || signum < 0) return -EINVAL;
if (signum >= NUMSIGNALS || signum < 0) return -EINVAL;
if (signum == SIGKILL || signum == SIGSTOP) return -EINVAL;
if (oldact) {