diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 1e34016..73de0c5 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -652,7 +652,7 @@ db_kill(dummy1, dummy2, dummy3, dummy4) if (PROC_TRYLOCK(p) == 0) DB_ERROR(("Can't lock process with pid %ld\n", (long) pid)); else { - psignal(p, sig); + pksignal(p, sig, NULL); PROC_UNLOCK(p); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index e174df1..61ea1d9 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -99,7 +99,8 @@ SDT_PROBE_ARGTYPE(proc, kernel, , signal_discard, 2, "int"); 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, + ksiginfo_t *ksi); static int issignal(struct thread *td, int stop_allowed); static int sigprop(int sig); static void tdsigwakeup(struct thread *, int, sig_t, int); @@ -1613,11 +1614,9 @@ kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss) * cp is calling process. */ static int -killpg1(td, sig, pgid, all) - register struct thread *td; - int sig, pgid, all; +killpg1(struct thread *td, int sig, int pgid, int all, ksiginfo_t *ksi) { - register struct proc *p; + struct proc *p; struct pgrp *pgrp; int nfound = 0; @@ -1636,7 +1635,7 @@ killpg1(td, sig, pgid, all) if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) - psignal(p, sig); + pksignal(p, sig, ksi); } PROC_UNLOCK(p); } @@ -1667,7 +1666,7 @@ killpg1(td, sig, pgid, all) if (p_cansignal(td, p, sig) == 0) { nfound++; if (sig) - psignal(p, sig); + pksignal(p, sig, ksi); } PROC_UNLOCK(p); } @@ -1684,11 +1683,10 @@ struct kill_args { #endif /* ARGSUSED */ int -kill(td, uap) - register struct thread *td; - register struct kill_args *uap; +kill(struct thread *td, struct kill_args *uap) { - register struct proc *p; + ksiginfo_t ksi; + struct proc *p; int error; AUDIT_ARG_SIGNUM(uap->signum); @@ -1696,6 +1694,12 @@ kill(td, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); + ksiginfo_init(&ksi); + ksi.ksi_signo = uap->signum; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + if (uap->pid > 0) { /* kill single process */ if ((p = pfind(uap->pid)) == NULL) { @@ -1705,17 +1709,17 @@ kill(td, uap) AUDIT_ARG_PROCESS(p); error = p_cansignal(td, p, uap->signum); if (error == 0 && uap->signum) - psignal(p, uap->signum); + pksignal(p, uap->signum, &ksi); PROC_UNLOCK(p); return (error); } switch (uap->pid) { case -1: /* broadcast signal */ - return (killpg1(td, uap->signum, 0, 1)); + return (killpg1(td, uap->signum, 0, 1, &ksi)); case 0: /* signal own process group */ - return (killpg1(td, uap->signum, 0, 0)); + return (killpg1(td, uap->signum, 0, 0, &ksi)); default: /* negative explicit process group */ - return (killpg1(td, uap->signum, -uap->pid, 0)); + return (killpg1(td, uap->signum, -uap->pid, 0, &ksi)); } /* NOTREACHED */ } @@ -1729,17 +1733,21 @@ struct okillpg_args { #endif /* ARGSUSED */ int -okillpg(td, uap) - struct thread *td; - register struct okillpg_args *uap; +okillpg(struct thread *td, struct okillpg_args *uap) { + ksiginfo_t ksi; AUDIT_ARG_SIGNUM(uap->signum); AUDIT_ARG_PID(uap->pgid); if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - return (killpg1(td, uap->signum, uap->pgid, 0)); + ksiginfo_init(&ksi); + ksi.ksi_signo = uap->signum; + ksi.ksi_code = SI_USER; + ksi.ksi_pid = td->td_proc->p_pid; + ksi.ksi_uid = td->td_ucred->cr_ruid; + return (killpg1(td, uap->signum, uap->pgid, 0, &ksi)); } #endif /* COMPAT_43 */ @@ -1789,8 +1797,7 @@ sigqueue(struct thread *td, struct sigqueue_args *uap) * Send a signal to a process group. */ void -gsignal(pgid, sig) - int pgid, sig; +gsignal(int pgid, int sig, ksiginfo_t *ksi) { struct pgrp *pgrp; @@ -1799,7 +1806,7 @@ gsignal(pgid, sig) pgrp = pgfind(pgid); sx_sunlock(&proctree_lock); if (pgrp != NULL) { - pgsignal(pgrp, sig, 0); + pgsignal(pgrp, sig, 0, ksi); PGRP_UNLOCK(pgrp); } } @@ -1810,18 +1817,16 @@ gsignal(pgid, sig) * limit to members which have a controlling terminal. */ void -pgsignal(pgrp, sig, checkctty) - struct pgrp *pgrp; - int sig, checkctty; +pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi) { - register struct proc *p; + struct proc *p; if (pgrp) { PGRP_LOCK_ASSERT(pgrp, MA_OWNED); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { PROC_LOCK(p); if (checkctty == 0 || p->p_flag & P_CONTROLT) - psignal(p, sig); + pksignal(p, sig, ksi); PROC_UNLOCK(p); } } @@ -1942,7 +1947,19 @@ sigtd(struct proc *p, int sig, int prop) void psignal(struct proc *p, int sig) { - (void) tdsignal(p, NULL, sig, NULL); + ksiginfo_t ksi; + + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; + (void) tdsignal(p, NULL, sig, &ksi); +} + +void +pksignal(struct proc *p, int sig, ksiginfo_t *ksi) +{ + + (void) tdsignal(p, NULL, sig, ksi); } int @@ -3144,8 +3161,13 @@ pgsigio(sigiop, sig, checkctty) struct sigio **sigiop; int sig, checkctty; { + ksiginfo_t ksi; struct sigio *sigio; + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; + SIGIO_LOCK(); sigio = *sigiop; if (sigio == NULL) { diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 81f6741..7e6cf00 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -355,6 +355,7 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig) { struct proc *p = td->td_proc; struct pgrp *pg; + ksiginfo_t ksi; int error; MPASS(sig == SIGTTIN || sig == SIGTTOU); @@ -396,8 +397,14 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig) * Send the signal and sleep until we're the new * foreground process group. */ + if (sig != 0) { + ksiginfo_init(&ksi); + ksi.ksi_code = SI_KERNEL; + ksi.ksi_signo = sig; + sig = 0; + } PGRP_LOCK(pg); - pgsignal(pg, sig, 1); + pgsignal(pg, ksi.ksi_signo, 1, &ksi); PGRP_UNLOCK(pg); error = tty_wait(tp, &tp->t_bgwait); @@ -1240,6 +1247,8 @@ tty_signal_sessleader(struct tty *tp, int sig) void tty_signal_pgrp(struct tty *tp, int sig) { + ksiginfo_t ksi; + tty_lock_assert(tp, MA_OWNED); MPASS(sig >= 1 && sig < NSIG); @@ -1249,8 +1258,11 @@ tty_signal_pgrp(struct tty *tp, int sig) if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO)) tty_info(tp); if (tp->t_pgrp != NULL) { + ksiginfo_init(&ksi); + ksi.ksi_signo = sig; + ksi.ksi_code = SI_KERNEL; PGRP_LOCK(tp->t_pgrp); - pgsignal(tp->t_pgrp, sig, 1); + pgsignal(tp->t_pgrp, sig, 1, &ksi); PGRP_UNLOCK(tp->t_pgrp); } } diff --git a/sys/sys/signal.h b/sys/sys/signal.h index e90b107..81d45a9 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -338,6 +338,7 @@ struct sigaction { /* an asynchronous I/O request.*/ #define SI_MESGQ 0x10005 /* Signal generated by arrival of a */ /* message on an empty message queue. */ +#define SI_KERNEL 0x10006 #endif #if __BSD_VISIBLE #define SI_UNDEFINED 0 diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index c27a128..e89905b 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -326,10 +326,11 @@ extern int kern_logsigexit; /* Sysctl variable kern.logsigexit */ */ int cursig(struct thread *td, int stop_allowed); void execsigs(struct proc *p); -void gsignal(int pgid, int sig); +void gsignal(int pgid, int sig, ksiginfo_t *ksi); void killproc(struct proc *p, char *why); +void pksignal(struct proc *p, int sig, ksiginfo_t *ksi); void pgsigio(struct sigio **, int signum, int checkctty); -void pgsignal(struct pgrp *pgrp, int sig, int checkctty); +void pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi); void postsig(int sig); void psignal(struct proc *p, int sig); int psignal_event(struct proc *p, struct sigevent *, ksiginfo_t *);