kernel: Allow sending signals to process groups from userspace

This commit is contained in:
apio 2023-09-18 07:19:53 +02:00
parent 4d6c8aa8bf
commit 08583d5ad4
Signed by: apio
GPG Key ID: B8A7D06E42258954

View File

@ -54,16 +54,65 @@ Result<u64> sys_kill(Registers*, SyscallArgs args)
pid_t pid = (pid_t)args[0]; pid_t pid = (pid_t)args[0];
int signo = (int)args[1]; int signo = (int)args[1];
// FIXME: Support this case. auto send_signal = [&](Thread* target) -> Result<void> {
if (pid <= 0) return err(ENOTSUP); if (current->auth.euid != 0 && current->auth.euid != target->auth.euid &&
current->auth.egid != target->auth.egid)
return err(EPERM);
if (target->is_kernel) return {};
if (signo == 0) return {};
auto* target = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH)); target->send_signal(signo);
if (current->auth.euid != 0 && current->auth.euid != target->auth.euid && current->auth.egid != target->auth.egid)
return err(EPERM);
if (target->is_kernel) return 0;
if (signo == 0) return 0;
target->send_signal(signo); return {};
};
if (pid > 0)
{
auto* target = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
TRY(send_signal(target));
}
else if (pid == 0)
{
int errno = -1;
bool pgid_exists = false;
Scheduler::for_each_in_process_group(current->pgid, [&](Thread* target) {
pgid_exists = true;
auto rc = send_signal(target);
if (rc.has_error())
{
errno = rc.error();
return false;
}
return true;
});
if (errno > 0) return err(errno);
if (!pgid_exists) return err(ESRCH);
}
else if (pid == -1)
{
for (auto* thread : g_threads)
{
// We ignore permission errors here.
if (thread != current && thread->id != 1) send_signal(thread);
}
}
else if (pid < -1)
{
int errno = -1;
bool pgid_exists = false;
Scheduler::for_each_in_process_group(-pid, [&](Thread* target) {
pgid_exists = true;
auto rc = send_signal(target);
if (rc.has_error())
{
errno = rc.error();
return false;
}
return true;
});
if (errno > 0) return err(errno);
if (!pgid_exists) return err(ESRCH);
}
return 0; return 0;
} }