diff options
author | sobomax <sobomax@FreeBSD.org> | 2005-02-13 16:42:08 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2005-02-13 16:42:08 +0000 |
commit | 1d558007d0e84104e9e49a8c08e4a4f6faad3a81 (patch) | |
tree | 55af5c404f315b928f52273e849b0e73080b7f0d /sys/kern/kern_sig.c | |
parent | 5775bba72ee8cddb1a59602a8d654da0e8f4e1b3 (diff) | |
download | FreeBSD-src-1d558007d0e84104e9e49a8c08e4a4f6faad3a81.zip FreeBSD-src-1d558007d0e84104e9e49a8c08e4a4f6faad3a81.tar.gz |
Split out kill(2) syscall service routine into user-level and kernel part, the
former is callable from user space and the latter from the kernel one. Make
kernel version take additional argument which tells if the respective call
should check for additional restrictions for sending signals to suid/sugid
applications or not.
Make all emulation layers using non-checked version, since signal numbers in
emulation layers can have different meaning that in native mode and such
protection can cause misbehaviour.
As a result remove LIBTHR from the signals allowed to be delivered to a
suid/sugid application.
Requested (sorta) by: rwatson
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 2889adb..0974801 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -82,7 +82,8 @@ __FBSDID("$FreeBSD$"); static int coredump(struct thread *); static char *expand_name(const char *, uid_t, pid_t); -static int killpg1(struct thread *td, int sig, int pgid, int all); +static int killpg1(struct thread *td, int sig, int pgid, int all, + int pedantic); static int issignal(struct thread *p); static int sigprop(int sig); static void stop(struct proc *); @@ -1299,9 +1300,9 @@ kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss) * cp is calling process. */ static int -killpg1(td, sig, pgid, all) +killpg1(td, sig, pgid, all, pedantic) register struct thread *td; - int sig, pgid, all; + int sig, pgid, all, pedantic; { register struct proc *p; struct pgrp *pgrp; @@ -1319,7 +1320,7 @@ killpg1(td, sig, pgid, all) PROC_UNLOCK(p); continue; } - if (p_cansignal(td, p, sig) == 0) { + if (p_cansignal(td, p, sig, pedantic) == 0) { nfound++; if (sig) psignal(p, sig); @@ -1344,12 +1345,12 @@ killpg1(td, sig, pgid, all) } sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_LOCK(p); if (p->p_pid <= 1 || p->p_flag & P_SYSTEM) { PROC_UNLOCK(p); continue; } - if (p_cansignal(td, p, sig) == 0) { + if (p_cansignal(td, p, sig, pedantic) == 0) { nfound++; if (sig) psignal(p, sig); @@ -1376,6 +1377,16 @@ kill(td, uap) register struct thread *td; register struct kill_args *uap; { + + return kern_kill(td, uap, 1); +} + +int +kern_kill(td, uap, pedantic) + struct thread *td; + struct kill_args *uap; + int pedantic; +{ register struct proc *p; int error; @@ -1388,7 +1399,7 @@ kill(td, uap) if ((p = zpfind(uap->pid)) == NULL) return (ESRCH); } - error = p_cansignal(td, p, uap->signum); + error = p_cansignal(td, p, uap->signum, pedantic); if (error == 0 && uap->signum) psignal(p, uap->signum); PROC_UNLOCK(p); @@ -1396,11 +1407,11 @@ kill(td, uap) } switch (uap->pid) { case -1: /* broadcast signal */ - return (killpg1(td, uap->signum, 0, 1)); + return (killpg1(td, uap->signum, 0, 1, pedantic)); case 0: /* signal own process group */ - return (killpg1(td, uap->signum, 0, 0)); + return (killpg1(td, uap->signum, 0, 0, pedantic)); default: /* negative explicit process group */ - return (killpg1(td, uap->signum, -uap->pid, 0)); + return (killpg1(td, uap->signum, -uap->pid, 0, pedantic)); } /* NOTREACHED */ } @@ -1424,7 +1435,7 @@ okillpg(td, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - return (killpg1(td, uap->signum, uap->pgid, 0)); + return (killpg1(td, uap->signum, uap->pgid, 0, 1)); } #endif /* COMPAT_43 */ |