mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
signal: do auth check
This commit is contained in:
@@ -13,7 +13,7 @@ pid_t jobctl_getpgid(proc_t *proc);
|
||||
pid_t jobctl_getsid(proc_t *proc);
|
||||
int jobctl_setctty(proc_t *proc, void *ctty, bool steal);
|
||||
void *jobctl_getctty(proc_t *proc);
|
||||
int jobctl_signal(proc_t *proc, int signal);
|
||||
int jobctl_signal(proc_t *proc, int signal, proc_t *sender);
|
||||
proc_t *jobctl_getforeground(proc_t *proc);
|
||||
int jobctl_setforeground(proc_t *session, proc_t *pgrp);
|
||||
|
||||
|
||||
+3
-3
@@ -74,7 +74,7 @@ void tty_process(tty_t *tty, char c) {
|
||||
if (signal >= 0) {
|
||||
proc_t *pgrp = getforeground(tty);
|
||||
if (pgrp) {
|
||||
jobctl_signal(pgrp, signal);
|
||||
jobctl_signal(pgrp, signal, NULL);
|
||||
PROC_RELEASE(pgrp);
|
||||
}
|
||||
return;
|
||||
@@ -311,7 +311,7 @@ int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cre
|
||||
|
||||
proc_t *foreground = getforeground(tty);
|
||||
if (foreground) {
|
||||
jobctl_signal(foreground, SIGWINCH);
|
||||
jobctl_signal(foreground, SIGWINCH, NULL);
|
||||
PROC_RELEASE(foreground);
|
||||
}
|
||||
break;
|
||||
@@ -524,7 +524,7 @@ void tty_unregister(tty_t *tty) {
|
||||
|
||||
proc_t *foreground = getforeground(tty);
|
||||
if (foreground) {
|
||||
jobctl_signal(foreground, SIGHUP);
|
||||
jobctl_signal(foreground, SIGHUP, NULL);
|
||||
PROC_RELEASE(foreground);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,6 @@ static int credlistener(cred_t *cred, int actions, void *arg0, void *arg1, void
|
||||
|
||||
static int process(cred_t *cred, int actions, void *arg0, void *arg1, void *arg2) {
|
||||
proc_t *proc = arg0;
|
||||
int *signal = arg1;
|
||||
|
||||
int weight = 0;
|
||||
if (actions & AUTH_ACTIONS_PROCESS_SIGNAL) {
|
||||
@@ -260,10 +259,6 @@ static int process(cred_t *cred, int actions, void *arg0, void *arg1, void *arg2
|
||||
cred->euid == proc->cred.uid ||
|
||||
cred->euid == proc->cred.suid)
|
||||
weight += 1;
|
||||
else if (*signal == SIGCONT) {
|
||||
// TODO SIGCONT is supposed to work on the same process group; we are being a bit more permissive here for now
|
||||
weight += 1;
|
||||
}
|
||||
|
||||
DONE_CHECK(actions);
|
||||
}
|
||||
|
||||
+17
-4
@@ -1,6 +1,7 @@
|
||||
#include <kernel/jobctl.h>
|
||||
#include <kernel/interrupt.h>
|
||||
#include <kernel/tty.h>
|
||||
#include <kernel/auth.h>
|
||||
#include <errno.h>
|
||||
#include <logging.h>
|
||||
|
||||
@@ -278,8 +279,8 @@ void jobctl_detach(proc_t *proc) {
|
||||
PROC_RELEASE(unholdsession);
|
||||
} else {
|
||||
jobctl_setctty(proc, NULL, 0);
|
||||
jobctl_signal(foreground, SIGHUP);
|
||||
jobctl_signal(foreground, SIGCONT);
|
||||
jobctl_signal(foreground, SIGHUP, NULL);
|
||||
jobctl_signal(foreground, SIGCONT, NULL);
|
||||
PROC_RELEASE(foreground);
|
||||
}
|
||||
}
|
||||
@@ -378,11 +379,13 @@ void jobctl_procremove(proc_t *proc) {
|
||||
|
||||
// proc can be null if the signal is being sent to the calling processes own process group
|
||||
// since that is only passed from a userland thread, we can assume _cpu()->thread->proc is not null
|
||||
int jobctl_signal(proc_t *proc, int signal) {
|
||||
int jobctl_signal(proc_t *proc, int signal, proc_t *sender) {
|
||||
int error = 0;
|
||||
bool intstatus = interrupt_set(false);
|
||||
proc_t *leader;
|
||||
proc_t *tmpproc = _cpu()->thread->proc;
|
||||
pid_t senderpgid = sender ? jobctl_getpgid(sender) : 0;
|
||||
|
||||
if (proc == NULL) {
|
||||
spinlock_acquire(&tmpproc->jobctllock);
|
||||
leader = tmpproc->pgrp.leader ? tmpproc->pgrp.leader : tmpproc;
|
||||
@@ -400,11 +403,21 @@ int jobctl_signal(proc_t *proc, int signal) {
|
||||
|
||||
spinlock_acquire(&leader->pgrp.lock);
|
||||
|
||||
size_t donecount = 0;
|
||||
proc_t *iterator = leader;
|
||||
while (iterator) {
|
||||
signal_signalproc(iterator, signal);
|
||||
// only send the signal if:
|
||||
// there isn't a specific sender (for example, ^C from the tty)
|
||||
// the signal is SIGCONT and they are from the same process group
|
||||
// the auth check passes
|
||||
if (senderpgid == 0 || (signal == SIGCONT && leader->pid == senderpgid) || auth_process_check(&sender->cred, AUTH_ACTIONS_PROCESS_SIGNAL, iterator) == 0) {
|
||||
signal_signalproc(iterator, signal);
|
||||
++donecount;
|
||||
}
|
||||
|
||||
iterator = iterator->pgrp.nextmember;
|
||||
}
|
||||
error = donecount == 0 ? EPERM : 0;
|
||||
|
||||
spinlock_release(&leader->pgrp.lock);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/jobctl.h>
|
||||
#include <kernel/auth.h>
|
||||
|
||||
syscallret_t syscall_kill(context_t *context, int pid, int signal) {
|
||||
syscallret_t ret = {
|
||||
@@ -30,16 +31,27 @@ syscallret_t syscall_kill(context_t *context, int pid, int signal) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pid >= 1)
|
||||
signal_signalproc(target, signal);
|
||||
else
|
||||
ret.errno = jobctl_signal(target, signal);
|
||||
// null signal is meant to find out about the existance of a process
|
||||
if (signal == 0)
|
||||
goto leave;
|
||||
|
||||
if (pid >= 1) {
|
||||
if (signal != SIGCONT && jobctl_getpgid(target) != jobctl_getpgid(_cpu()->thread->proc)) {
|
||||
ret.errno = auth_process_check(&_cpu()->thread->proc->cred, AUTH_ACTIONS_PROCESS_SIGNAL, target);
|
||||
if (ret.errno)
|
||||
goto leave;
|
||||
}
|
||||
|
||||
signal_signalproc(target, signal);
|
||||
} else {
|
||||
ret.errno = jobctl_signal(target, signal, _cpu()->thread->proc);
|
||||
}
|
||||
|
||||
leave:
|
||||
if (target) {
|
||||
PROC_RELEASE(target);
|
||||
}
|
||||
|
||||
ret.errno = 0;
|
||||
ret.ret = 0;
|
||||
ret.ret = ret.errno ? -1 : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user