Annotation of sys/kern/kern_sig.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: kern_sig.c,v 1.94 2007/05/30 07:42:52 moritz Exp $ */
! 2: /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1997 Theo de Raadt. All rights reserved.
! 6: * Copyright (c) 1982, 1986, 1989, 1991, 1993
! 7: * The Regents of the University of California. All rights reserved.
! 8: * (c) UNIX System Laboratories, Inc.
! 9: * All or some portions of this file are derived from material licensed
! 10: * to the University of California by American Telephone and Telegraph
! 11: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
! 12: * the permission of UNIX System Laboratories, Inc.
! 13: *
! 14: * Redistribution and use in source and binary forms, with or without
! 15: * modification, are permitted provided that the following conditions
! 16: * are met:
! 17: * 1. Redistributions of source code must retain the above copyright
! 18: * notice, this list of conditions and the following disclaimer.
! 19: * 2. Redistributions in binary form must reproduce the above copyright
! 20: * notice, this list of conditions and the following disclaimer in the
! 21: * documentation and/or other materials provided with the distribution.
! 22: * 3. Neither the name of the University nor the names of its contributors
! 23: * may be used to endorse or promote products derived from this software
! 24: * without specific prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 36: * SUCH DAMAGE.
! 37: *
! 38: * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
! 39: */
! 40:
! 41: #define SIGPROP /* include signal properties table */
! 42: #include <sys/param.h>
! 43: #include <sys/signalvar.h>
! 44: #include <sys/resourcevar.h>
! 45: #include <sys/queue.h>
! 46: #include <sys/namei.h>
! 47: #include <sys/vnode.h>
! 48: #include <sys/event.h>
! 49: #include <sys/proc.h>
! 50: #include <sys/systm.h>
! 51: #include <sys/timeb.h>
! 52: #include <sys/times.h>
! 53: #include <sys/buf.h>
! 54: #include <sys/acct.h>
! 55: #include <sys/file.h>
! 56: #include <sys/kernel.h>
! 57: #include <sys/wait.h>
! 58: #include <sys/ktrace.h>
! 59: #include <sys/stat.h>
! 60: #include <sys/core.h>
! 61: #include <sys/malloc.h>
! 62: #include <sys/pool.h>
! 63: #include <sys/ptrace.h>
! 64: #include <sys/sched.h>
! 65:
! 66: #include <sys/mount.h>
! 67: #include <sys/syscallargs.h>
! 68:
! 69: #include <machine/cpu.h>
! 70:
! 71: #include <uvm/uvm_extern.h>
! 72: #include <sys/user.h> /* for coredump */
! 73:
! 74: int filt_sigattach(struct knote *kn);
! 75: void filt_sigdetach(struct knote *kn);
! 76: int filt_signal(struct knote *kn, long hint);
! 77:
! 78: struct filterops sig_filtops =
! 79: { 0, filt_sigattach, filt_sigdetach, filt_signal };
! 80:
! 81: void proc_stop(struct proc *p, int);
! 82: void proc_stop_sweep(void *);
! 83: struct timeout proc_stop_to;
! 84:
! 85: int cansignal(struct proc *, struct pcred *, struct proc *, int);
! 86:
! 87: struct pool sigacts_pool; /* memory pool for sigacts structures */
! 88:
! 89: /*
! 90: * Can process p, with pcred pc, send the signal signum to process q?
! 91: */
! 92: int
! 93: cansignal(struct proc *p, struct pcred *pc, struct proc *q, int signum)
! 94: {
! 95: if (pc->pc_ucred->cr_uid == 0)
! 96: return (1); /* root can always signal */
! 97:
! 98: if (p == q)
! 99: return (1); /* process can always signal itself */
! 100:
! 101: #ifdef RTHREADS
! 102: /* a thread can only be signalled from within the same process */
! 103: if (q->p_flag & P_THREAD) {
! 104: return (p->p_p == q->p_p);
! 105: }
! 106: #endif
! 107:
! 108: if (signum == SIGCONT && q->p_session == p->p_session)
! 109: return (1); /* SIGCONT in session */
! 110:
! 111: /*
! 112: * Using kill(), only certain signals can be sent to setugid
! 113: * child processes
! 114: */
! 115: if (q->p_flag & P_SUGID) {
! 116: switch (signum) {
! 117: case 0:
! 118: case SIGKILL:
! 119: case SIGINT:
! 120: case SIGTERM:
! 121: case SIGALRM:
! 122: case SIGSTOP:
! 123: case SIGTTIN:
! 124: case SIGTTOU:
! 125: case SIGTSTP:
! 126: case SIGHUP:
! 127: case SIGUSR1:
! 128: case SIGUSR2:
! 129: if (pc->p_ruid == q->p_cred->p_ruid ||
! 130: pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
! 131: pc->p_ruid == q->p_ucred->cr_uid ||
! 132: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
! 133: return (1);
! 134: }
! 135: return (0);
! 136: }
! 137:
! 138: /* XXX
! 139: * because the P_SUGID test exists, this has extra tests which
! 140: * could be removed.
! 141: */
! 142: if (pc->p_ruid == q->p_cred->p_ruid ||
! 143: pc->p_ruid == q->p_cred->p_svuid ||
! 144: pc->pc_ucred->cr_uid == q->p_cred->p_ruid ||
! 145: pc->pc_ucred->cr_uid == q->p_cred->p_svuid ||
! 146: pc->p_ruid == q->p_ucred->cr_uid ||
! 147: pc->pc_ucred->cr_uid == q->p_ucred->cr_uid)
! 148: return (1);
! 149: return (0);
! 150: }
! 151:
! 152: /*
! 153: * Initialize signal-related data structures.
! 154: */
! 155: void
! 156: signal_init(void)
! 157: {
! 158: timeout_set(&proc_stop_to, proc_stop_sweep, NULL);
! 159:
! 160: pool_init(&sigacts_pool, sizeof(struct sigacts), 0, 0, 0, "sigapl",
! 161: &pool_allocator_nointr);
! 162: }
! 163:
! 164: /*
! 165: * Create an initial sigacts structure, using the same signal state
! 166: * as p.
! 167: */
! 168: struct sigacts *
! 169: sigactsinit(struct proc *p)
! 170: {
! 171: struct sigacts *ps;
! 172:
! 173: ps = pool_get(&sigacts_pool, PR_WAITOK);
! 174: memcpy(ps, p->p_sigacts, sizeof(struct sigacts));
! 175: ps->ps_refcnt = 1;
! 176: return (ps);
! 177: }
! 178:
! 179: /*
! 180: * Make p2 share p1's sigacts.
! 181: */
! 182: void
! 183: sigactsshare(struct proc *p1, struct proc *p2)
! 184: {
! 185:
! 186: p2->p_sigacts = p1->p_sigacts;
! 187: p1->p_sigacts->ps_refcnt++;
! 188: }
! 189:
! 190: /*
! 191: * Make this process not share its sigacts, maintaining all
! 192: * signal state.
! 193: */
! 194: void
! 195: sigactsunshare(struct proc *p)
! 196: {
! 197: struct sigacts *newps;
! 198:
! 199: if (p->p_sigacts->ps_refcnt == 1)
! 200: return;
! 201:
! 202: newps = sigactsinit(p);
! 203: sigactsfree(p);
! 204: p->p_sigacts = newps;
! 205: }
! 206:
! 207: /*
! 208: * Release a sigacts structure.
! 209: */
! 210: void
! 211: sigactsfree(struct proc *p)
! 212: {
! 213: struct sigacts *ps = p->p_sigacts;
! 214:
! 215: if (--ps->ps_refcnt > 0)
! 216: return;
! 217:
! 218: p->p_sigacts = NULL;
! 219:
! 220: pool_put(&sigacts_pool, ps);
! 221: }
! 222:
! 223: /* ARGSUSED */
! 224: int
! 225: sys_sigaction(struct proc *p, void *v, register_t *retval)
! 226: {
! 227: struct sys_sigaction_args /* {
! 228: syscallarg(int) signum;
! 229: syscallarg(const struct sigaction *) nsa;
! 230: syscallarg(struct sigaction *) osa;
! 231: } */ *uap = v;
! 232: struct sigaction vec;
! 233: struct sigaction *sa;
! 234: struct sigacts *ps = p->p_sigacts;
! 235: int signum;
! 236: int bit, error;
! 237:
! 238: signum = SCARG(uap, signum);
! 239: if (signum <= 0 || signum >= NSIG ||
! 240: (SCARG(uap, nsa) && (signum == SIGKILL || signum == SIGSTOP)))
! 241: return (EINVAL);
! 242: sa = &vec;
! 243: if (SCARG(uap, osa)) {
! 244: sa->sa_handler = ps->ps_sigact[signum];
! 245: sa->sa_mask = ps->ps_catchmask[signum];
! 246: bit = sigmask(signum);
! 247: sa->sa_flags = 0;
! 248: if ((ps->ps_sigonstack & bit) != 0)
! 249: sa->sa_flags |= SA_ONSTACK;
! 250: if ((ps->ps_sigintr & bit) == 0)
! 251: sa->sa_flags |= SA_RESTART;
! 252: if ((ps->ps_sigreset & bit) != 0)
! 253: sa->sa_flags |= SA_RESETHAND;
! 254: if ((ps->ps_siginfo & bit) != 0)
! 255: sa->sa_flags |= SA_SIGINFO;
! 256: if (signum == SIGCHLD) {
! 257: if ((p->p_flag & P_NOCLDSTOP) != 0)
! 258: sa->sa_flags |= SA_NOCLDSTOP;
! 259: if ((p->p_flag & P_NOCLDWAIT) != 0)
! 260: sa->sa_flags |= SA_NOCLDWAIT;
! 261: }
! 262: if ((sa->sa_mask & bit) == 0)
! 263: sa->sa_flags |= SA_NODEFER;
! 264: sa->sa_mask &= ~bit;
! 265: error = copyout(sa, SCARG(uap, osa), sizeof (vec));
! 266: if (error)
! 267: return (error);
! 268: }
! 269: if (SCARG(uap, nsa)) {
! 270: error = copyin(SCARG(uap, nsa), sa, sizeof (vec));
! 271: if (error)
! 272: return (error);
! 273: setsigvec(p, signum, sa);
! 274: }
! 275: return (0);
! 276: }
! 277:
! 278: void
! 279: setsigvec(struct proc *p, int signum, struct sigaction *sa)
! 280: {
! 281: struct sigacts *ps = p->p_sigacts;
! 282: int bit;
! 283: int s;
! 284:
! 285: bit = sigmask(signum);
! 286: /*
! 287: * Change setting atomically.
! 288: */
! 289: s = splhigh();
! 290: ps->ps_sigact[signum] = sa->sa_handler;
! 291: if ((sa->sa_flags & SA_NODEFER) == 0)
! 292: sa->sa_mask |= sigmask(signum);
! 293: ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
! 294: if (signum == SIGCHLD) {
! 295: if (sa->sa_flags & SA_NOCLDSTOP)
! 296: atomic_setbits_int(&p->p_flag, P_NOCLDSTOP);
! 297: else
! 298: atomic_clearbits_int(&p->p_flag, P_NOCLDSTOP);
! 299: /*
! 300: * If the SA_NOCLDWAIT flag is set or the handler
! 301: * is SIG_IGN we reparent the dying child to PID 1
! 302: * (init) which will reap the zombie. Because we use
! 303: * init to do our dirty work we never set P_NOCLDWAIT
! 304: * for PID 1.
! 305: */
! 306: if (p->p_pid != 1 && ((sa->sa_flags & SA_NOCLDWAIT) ||
! 307: sa->sa_handler == SIG_IGN))
! 308: atomic_setbits_int(&p->p_flag, P_NOCLDWAIT);
! 309: else
! 310: atomic_clearbits_int(&p->p_flag, P_NOCLDWAIT);
! 311: }
! 312: if ((sa->sa_flags & SA_RESETHAND) != 0)
! 313: ps->ps_sigreset |= bit;
! 314: else
! 315: ps->ps_sigreset &= ~bit;
! 316: if ((sa->sa_flags & SA_SIGINFO) != 0)
! 317: ps->ps_siginfo |= bit;
! 318: else
! 319: ps->ps_siginfo &= ~bit;
! 320: if ((sa->sa_flags & SA_RESTART) == 0)
! 321: ps->ps_sigintr |= bit;
! 322: else
! 323: ps->ps_sigintr &= ~bit;
! 324: if ((sa->sa_flags & SA_ONSTACK) != 0)
! 325: ps->ps_sigonstack |= bit;
! 326: else
! 327: ps->ps_sigonstack &= ~bit;
! 328: #ifdef COMPAT_SUNOS
! 329: {
! 330: extern struct emul emul_sunos;
! 331: if (p->p_emul == &emul_sunos) {
! 332: if (sa->sa_flags & SA_USERTRAMP)
! 333: ps->ps_usertramp |= bit;
! 334: else
! 335: ps->ps_usertramp &= ~bit;
! 336: }
! 337: }
! 338: #endif
! 339: /*
! 340: * Set bit in p_sigignore for signals that are set to SIG_IGN,
! 341: * and for signals set to SIG_DFL where the default is to ignore.
! 342: * However, don't put SIGCONT in p_sigignore,
! 343: * as we have to restart the process.
! 344: */
! 345: if (sa->sa_handler == SIG_IGN ||
! 346: (sigprop[signum] & SA_IGNORE && sa->sa_handler == SIG_DFL)) {
! 347: atomic_clearbits_int(&p->p_siglist, bit);
! 348: if (signum != SIGCONT)
! 349: p->p_sigignore |= bit; /* easier in psignal */
! 350: p->p_sigcatch &= ~bit;
! 351: } else {
! 352: p->p_sigignore &= ~bit;
! 353: if (sa->sa_handler == SIG_DFL)
! 354: p->p_sigcatch &= ~bit;
! 355: else
! 356: p->p_sigcatch |= bit;
! 357: }
! 358: splx(s);
! 359: }
! 360:
! 361: /*
! 362: * Initialize signal state for process 0;
! 363: * set to ignore signals that are ignored by default.
! 364: */
! 365: void
! 366: siginit(struct proc *p)
! 367: {
! 368: int i;
! 369:
! 370: for (i = 0; i < NSIG; i++)
! 371: if (sigprop[i] & SA_IGNORE && i != SIGCONT)
! 372: p->p_sigignore |= sigmask(i);
! 373: }
! 374:
! 375: /*
! 376: * Reset signals for an exec of the specified process.
! 377: */
! 378: void
! 379: execsigs(struct proc *p)
! 380: {
! 381: struct sigacts *ps;
! 382: int nc, mask;
! 383:
! 384: sigactsunshare(p);
! 385: ps = p->p_sigacts;
! 386:
! 387: /*
! 388: * Reset caught signals. Held signals remain held
! 389: * through p_sigmask (unless they were caught,
! 390: * and are now ignored by default).
! 391: */
! 392: while (p->p_sigcatch) {
! 393: nc = ffs((long)p->p_sigcatch);
! 394: mask = sigmask(nc);
! 395: p->p_sigcatch &= ~mask;
! 396: if (sigprop[nc] & SA_IGNORE) {
! 397: if (nc != SIGCONT)
! 398: p->p_sigignore |= mask;
! 399: atomic_clearbits_int(&p->p_siglist, mask);
! 400: }
! 401: ps->ps_sigact[nc] = SIG_DFL;
! 402: }
! 403: /*
! 404: * Reset stack state to the user stack.
! 405: * Clear set of signals caught on the signal stack.
! 406: */
! 407: ps->ps_sigstk.ss_flags = SS_DISABLE;
! 408: ps->ps_sigstk.ss_size = 0;
! 409: ps->ps_sigstk.ss_sp = 0;
! 410: ps->ps_flags = 0;
! 411: atomic_clearbits_int(&p->p_flag, P_NOCLDWAIT);
! 412: if (ps->ps_sigact[SIGCHLD] == SIG_IGN)
! 413: ps->ps_sigact[SIGCHLD] = SIG_DFL;
! 414: }
! 415:
! 416: /*
! 417: * Manipulate signal mask.
! 418: * Note that we receive new mask, not pointer,
! 419: * and return old mask as return value;
! 420: * the library stub does the rest.
! 421: */
! 422: int
! 423: sys_sigprocmask(struct proc *p, void *v, register_t *retval)
! 424: {
! 425: struct sys_sigprocmask_args /* {
! 426: syscallarg(int) how;
! 427: syscallarg(sigset_t) mask;
! 428: } */ *uap = v;
! 429: int error = 0;
! 430: int s;
! 431:
! 432: *retval = p->p_sigmask;
! 433: s = splhigh();
! 434:
! 435: switch (SCARG(uap, how)) {
! 436: case SIG_BLOCK:
! 437: p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask;
! 438: break;
! 439:
! 440: case SIG_UNBLOCK:
! 441: p->p_sigmask &= ~SCARG(uap, mask);
! 442: break;
! 443:
! 444: case SIG_SETMASK:
! 445: p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
! 446: break;
! 447:
! 448: default:
! 449: error = EINVAL;
! 450: break;
! 451: }
! 452: splx(s);
! 453: return (error);
! 454: }
! 455:
! 456: /* ARGSUSED */
! 457: int
! 458: sys_sigpending(struct proc *p, void *v, register_t *retval)
! 459: {
! 460:
! 461: *retval = p->p_siglist;
! 462: return (0);
! 463: }
! 464:
! 465: /*
! 466: * Suspend process until signal, providing mask to be set
! 467: * in the meantime. Note nonstandard calling convention:
! 468: * libc stub passes mask, not pointer, to save a copyin.
! 469: */
! 470: /* ARGSUSED */
! 471: int
! 472: sys_sigsuspend(struct proc *p, void *v, register_t *retval)
! 473: {
! 474: struct sys_sigsuspend_args /* {
! 475: syscallarg(int) mask;
! 476: } */ *uap = v;
! 477: struct sigacts *ps = p->p_sigacts;
! 478:
! 479: /*
! 480: * When returning from sigpause, we want
! 481: * the old mask to be restored after the
! 482: * signal handler has finished. Thus, we
! 483: * save it here and mark the sigacts structure
! 484: * to indicate this.
! 485: */
! 486: ps->ps_oldmask = p->p_sigmask;
! 487: ps->ps_flags |= SAS_OLDMASK;
! 488: p->p_sigmask = SCARG(uap, mask) &~ sigcantmask;
! 489: while (tsleep(ps, PPAUSE|PCATCH, "pause", 0) == 0)
! 490: /* void */;
! 491: /* always return EINTR rather than ERESTART... */
! 492: return (EINTR);
! 493: }
! 494:
! 495: /* ARGSUSED */
! 496: int
! 497: sys_osigaltstack(struct proc *p, void *v, register_t *retval)
! 498: {
! 499: struct sys_osigaltstack_args /* {
! 500: syscallarg(const struct osigaltstack *) nss;
! 501: syscallarg(struct osigaltstack *) oss;
! 502: } */ *uap = v;
! 503: struct sigacts *psp;
! 504: struct osigaltstack ss;
! 505: int error;
! 506:
! 507: psp = p->p_sigacts;
! 508: if ((psp->ps_flags & SAS_ALTSTACK) == 0)
! 509: psp->ps_sigstk.ss_flags |= SS_DISABLE;
! 510: if (SCARG(uap, oss)) {
! 511: ss.ss_sp = psp->ps_sigstk.ss_sp;
! 512: ss.ss_size = psp->ps_sigstk.ss_size;
! 513: ss.ss_flags = psp->ps_sigstk.ss_flags;
! 514: if ((error = copyout(&ss, SCARG(uap, oss), sizeof(ss))))
! 515: return (error);
! 516: }
! 517: if (SCARG(uap, nss) == NULL)
! 518: return (0);
! 519: error = copyin(SCARG(uap, nss), &ss, sizeof(ss));
! 520: if (error)
! 521: return (error);
! 522: if (ss.ss_flags & SS_DISABLE) {
! 523: if (psp->ps_sigstk.ss_flags & SS_ONSTACK)
! 524: return (EINVAL);
! 525: psp->ps_flags &= ~SAS_ALTSTACK;
! 526: psp->ps_sigstk.ss_flags = ss.ss_flags;
! 527: return (0);
! 528: }
! 529: if (ss.ss_size < MINSIGSTKSZ)
! 530: return (ENOMEM);
! 531: psp->ps_flags |= SAS_ALTSTACK;
! 532: psp->ps_sigstk.ss_sp = ss.ss_sp;
! 533: psp->ps_sigstk.ss_size = ss.ss_size;
! 534: psp->ps_sigstk.ss_flags = ss.ss_flags;
! 535: return (0);
! 536: }
! 537:
! 538: int
! 539: sys_sigaltstack(struct proc *p, void *v, register_t *retval)
! 540: {
! 541: struct sys_sigaltstack_args /* {
! 542: syscallarg(const struct sigaltstack *) nss;
! 543: syscallarg(struct sigaltstack *) oss;
! 544: } */ *uap = v;
! 545: struct sigacts *psp;
! 546: struct sigaltstack ss;
! 547: int error;
! 548:
! 549: psp = p->p_sigacts;
! 550: if ((psp->ps_flags & SAS_ALTSTACK) == 0)
! 551: psp->ps_sigstk.ss_flags |= SS_DISABLE;
! 552: if (SCARG(uap, oss) && (error = copyout(&psp->ps_sigstk,
! 553: SCARG(uap, oss), sizeof(struct sigaltstack))))
! 554: return (error);
! 555: if (SCARG(uap, nss) == NULL)
! 556: return (0);
! 557: error = copyin(SCARG(uap, nss), &ss, sizeof(ss));
! 558: if (error)
! 559: return (error);
! 560: if (ss.ss_flags & SS_DISABLE) {
! 561: if (psp->ps_sigstk.ss_flags & SS_ONSTACK)
! 562: return (EINVAL);
! 563: psp->ps_flags &= ~SAS_ALTSTACK;
! 564: psp->ps_sigstk.ss_flags = ss.ss_flags;
! 565: return (0);
! 566: }
! 567: if (ss.ss_size < MINSIGSTKSZ)
! 568: return (ENOMEM);
! 569: psp->ps_flags |= SAS_ALTSTACK;
! 570: psp->ps_sigstk = ss;
! 571: return (0);
! 572: }
! 573:
! 574: /* ARGSUSED */
! 575: int
! 576: sys_kill(struct proc *cp, void *v, register_t *retval)
! 577: {
! 578: struct sys_kill_args /* {
! 579: syscallarg(int) pid;
! 580: syscallarg(int) signum;
! 581: } */ *uap = v;
! 582: struct proc *p;
! 583: struct pcred *pc = cp->p_cred;
! 584:
! 585: if ((u_int)SCARG(uap, signum) >= NSIG)
! 586: return (EINVAL);
! 587: if (SCARG(uap, pid) > 0) {
! 588: /* kill single process */
! 589: if ((p = pfind(SCARG(uap, pid))) == NULL)
! 590: return (ESRCH);
! 591: if (!cansignal(cp, pc, p, SCARG(uap, signum)))
! 592: return (EPERM);
! 593: if (SCARG(uap, signum))
! 594: psignal(p, SCARG(uap, signum));
! 595: return (0);
! 596: }
! 597: switch (SCARG(uap, pid)) {
! 598: case -1: /* broadcast signal */
! 599: return (killpg1(cp, SCARG(uap, signum), 0, 1));
! 600: case 0: /* signal own process group */
! 601: return (killpg1(cp, SCARG(uap, signum), 0, 0));
! 602: default: /* negative explicit process group */
! 603: return (killpg1(cp, SCARG(uap, signum), -SCARG(uap, pid), 0));
! 604: }
! 605: /* NOTREACHED */
! 606: }
! 607:
! 608: /*
! 609: * Common code for kill process group/broadcast kill.
! 610: * cp is calling process.
! 611: */
! 612: int
! 613: killpg1(struct proc *cp, int signum, int pgid, int all)
! 614: {
! 615: struct proc *p;
! 616: struct pcred *pc = cp->p_cred;
! 617: struct pgrp *pgrp;
! 618: int nfound = 0;
! 619:
! 620: if (all)
! 621: /*
! 622: * broadcast
! 623: */
! 624: for (p = LIST_FIRST(&allproc); p; p = LIST_NEXT(p, p_list)) {
! 625: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
! 626: p == cp || !cansignal(cp, pc, p, signum))
! 627: continue;
! 628: nfound++;
! 629: if (signum)
! 630: psignal(p, signum);
! 631: }
! 632: else {
! 633: if (pgid == 0)
! 634: /*
! 635: * zero pgid means send to my process group.
! 636: */
! 637: pgrp = cp->p_pgrp;
! 638: else {
! 639: pgrp = pgfind(pgid);
! 640: if (pgrp == NULL)
! 641: return (ESRCH);
! 642: }
! 643: LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
! 644: if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
! 645: !cansignal(cp, pc, p, signum))
! 646: continue;
! 647: nfound++;
! 648: if (signum && P_ZOMBIE(p) == 0)
! 649: psignal(p, signum);
! 650: }
! 651: }
! 652: return (nfound ? 0 : ESRCH);
! 653: }
! 654:
! 655: #define CANDELIVER(uid, euid, p) \
! 656: (euid == 0 || \
! 657: (uid) == (p)->p_cred->p_ruid || \
! 658: (uid) == (p)->p_cred->p_svuid || \
! 659: (uid) == (p)->p_ucred->cr_uid || \
! 660: (euid) == (p)->p_cred->p_ruid || \
! 661: (euid) == (p)->p_cred->p_svuid || \
! 662: (euid) == (p)->p_ucred->cr_uid)
! 663:
! 664: /*
! 665: * Deliver signum to pgid, but first check uid/euid against each
! 666: * process and see if it is permitted.
! 667: */
! 668: void
! 669: csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
! 670: {
! 671: struct pgrp *pgrp;
! 672: struct proc *p;
! 673:
! 674: if (pgid == 0)
! 675: return;
! 676: if (pgid < 0) {
! 677: pgid = -pgid;
! 678: if ((pgrp = pgfind(pgid)) == NULL)
! 679: return;
! 680: LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
! 681: if (CANDELIVER(uid, euid, p))
! 682: psignal(p, signum);
! 683: } else {
! 684: if ((p = pfind(pgid)) == NULL)
! 685: return;
! 686: if (CANDELIVER(uid, euid, p))
! 687: psignal(p, signum);
! 688: }
! 689: }
! 690:
! 691: /*
! 692: * Send a signal to a process group.
! 693: */
! 694: void
! 695: gsignal(int pgid, int signum)
! 696: {
! 697: struct pgrp *pgrp;
! 698:
! 699: if (pgid && (pgrp = pgfind(pgid)))
! 700: pgsignal(pgrp, signum, 0);
! 701: }
! 702:
! 703: /*
! 704: * Send a signal to a process group. If checktty is 1,
! 705: * limit to members which have a controlling terminal.
! 706: */
! 707: void
! 708: pgsignal(struct pgrp *pgrp, int signum, int checkctty)
! 709: {
! 710: struct proc *p;
! 711:
! 712: if (pgrp)
! 713: LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
! 714: if ((checkctty == 0 || p->p_flag & P_CONTROLT) &&
! 715: (p->p_flag & P_THREAD) == 0)
! 716: psignal(p, signum);
! 717: }
! 718:
! 719: /*
! 720: * Send a signal caused by a trap to the current process.
! 721: * If it will be caught immediately, deliver it with correct code.
! 722: * Otherwise, post it normally.
! 723: */
! 724: void
! 725: trapsignal(struct proc *p, int signum, u_long code, int type,
! 726: union sigval sigval)
! 727: {
! 728: struct sigacts *ps = p->p_sigacts;
! 729: int mask;
! 730:
! 731: mask = sigmask(signum);
! 732: if ((p->p_flag & P_TRACED) == 0 && (p->p_sigcatch & mask) != 0 &&
! 733: (p->p_sigmask & mask) == 0) {
! 734: #ifdef KTRACE
! 735: if (KTRPOINT(p, KTR_PSIG)) {
! 736: siginfo_t si;
! 737:
! 738: initsiginfo(&si, signum, code, type, sigval);
! 739: ktrpsig(p, signum, ps->ps_sigact[signum],
! 740: p->p_sigmask, type, &si);
! 741: }
! 742: #endif
! 743: p->p_stats->p_ru.ru_nsignals++;
! 744: (*p->p_emul->e_sendsig)(ps->ps_sigact[signum], signum,
! 745: p->p_sigmask, code, type, sigval);
! 746: p->p_sigmask |= ps->ps_catchmask[signum];
! 747: if ((ps->ps_sigreset & mask) != 0) {
! 748: p->p_sigcatch &= ~mask;
! 749: if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
! 750: p->p_sigignore |= mask;
! 751: ps->ps_sigact[signum] = SIG_DFL;
! 752: }
! 753: } else {
! 754: ps->ps_sig = signum;
! 755: ps->ps_code = code; /* XXX for core dump/debugger */
! 756: ps->ps_type = type;
! 757: ps->ps_sigval = sigval;
! 758: psignal(p, signum);
! 759: }
! 760: }
! 761:
! 762: /*
! 763: * Send the signal to the process. If the signal has an action, the action
! 764: * is usually performed by the target process rather than the caller; we add
! 765: * the signal to the set of pending signals for the process.
! 766: *
! 767: * Exceptions:
! 768: * o When a stop signal is sent to a sleeping process that takes the
! 769: * default action, the process is stopped without awakening it.
! 770: * o SIGCONT restarts stopped processes (or puts them back to sleep)
! 771: * regardless of the signal action (eg, blocked or ignored).
! 772: *
! 773: * Other ignored signals are discarded immediately.
! 774: */
! 775: void
! 776: psignal(struct proc *p, int signum)
! 777: {
! 778: int s, prop;
! 779: sig_t action;
! 780: int mask;
! 781: #ifdef RTHREADS
! 782: struct proc *q;
! 783: #endif
! 784: int wakeparent = 0;
! 785:
! 786: #ifdef DIAGNOSTIC
! 787: if ((u_int)signum >= NSIG || signum == 0)
! 788: panic("psignal signal number");
! 789: #endif
! 790:
! 791: /* Ignore signal if we are exiting */
! 792: if (p->p_flag & P_WEXIT)
! 793: return;
! 794:
! 795: #ifdef RTHREADS
! 796: TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
! 797: if (q == p)
! 798: continue;
! 799: if (q->p_sigdivert & (1 << signum)) {
! 800: q->p_sigdivert = 0;
! 801: psignal(q, signum);
! 802: return;
! 803: }
! 804: }
! 805: #endif
! 806:
! 807: KNOTE(&p->p_klist, NOTE_SIGNAL | signum);
! 808:
! 809: mask = sigmask(signum);
! 810: prop = sigprop[signum];
! 811:
! 812: /*
! 813: * If proc is traced, always give parent a chance.
! 814: */
! 815: if (p->p_flag & P_TRACED)
! 816: action = SIG_DFL;
! 817: else {
! 818: /*
! 819: * If the signal is being ignored,
! 820: * then we forget about it immediately.
! 821: * (Note: we don't set SIGCONT in p_sigignore,
! 822: * and if it is set to SIG_IGN,
! 823: * action will be SIG_DFL here.)
! 824: */
! 825: if (p->p_sigignore & mask)
! 826: return;
! 827: if (p->p_sigmask & mask)
! 828: action = SIG_HOLD;
! 829: else if (p->p_sigcatch & mask)
! 830: action = SIG_CATCH;
! 831: else {
! 832: action = SIG_DFL;
! 833:
! 834: if (prop & SA_KILL && p->p_nice > NZERO)
! 835: p->p_nice = NZERO;
! 836:
! 837: /*
! 838: * If sending a tty stop signal to a member of an
! 839: * orphaned process group, discard the signal here if
! 840: * the action is default; don't stop the process below
! 841: * if sleeping, and don't clear any pending SIGCONT.
! 842: */
! 843: if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0)
! 844: return;
! 845: }
! 846: }
! 847:
! 848: if (prop & SA_CONT) {
! 849: #ifdef RTHREADS
! 850: TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
! 851: if (q != p)
! 852: psignal(q, signum);
! 853: }
! 854: #endif
! 855: atomic_clearbits_int(&p->p_siglist, stopsigmask);
! 856: }
! 857:
! 858: if (prop & SA_STOP) {
! 859: #ifdef RTHREADS
! 860:
! 861: TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) {
! 862: if (q != p)
! 863: psignal(q, signum);
! 864: }
! 865: #endif
! 866: atomic_clearbits_int(&p->p_siglist, contsigmask);
! 867: atomic_clearbits_int(&p->p_flag, P_CONTINUED);
! 868: }
! 869:
! 870: atomic_setbits_int(&p->p_siglist, mask);
! 871:
! 872: /*
! 873: * Defer further processing for signals which are held,
! 874: * except that stopped processes must be continued by SIGCONT.
! 875: */
! 876: if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP))
! 877: return;
! 878:
! 879: SCHED_LOCK(s);
! 880:
! 881: switch (p->p_stat) {
! 882:
! 883: case SSLEEP:
! 884: /*
! 885: * If process is sleeping uninterruptibly
! 886: * we can't interrupt the sleep... the signal will
! 887: * be noticed when the process returns through
! 888: * trap() or syscall().
! 889: */
! 890: if ((p->p_flag & P_SINTR) == 0)
! 891: goto out;
! 892: /*
! 893: * Process is sleeping and traced... make it runnable
! 894: * so it can discover the signal in issignal() and stop
! 895: * for the parent.
! 896: */
! 897: if (p->p_flag & P_TRACED)
! 898: goto run;
! 899: /*
! 900: * If SIGCONT is default (or ignored) and process is
! 901: * asleep, we are finished; the process should not
! 902: * be awakened.
! 903: */
! 904: if ((prop & SA_CONT) && action == SIG_DFL) {
! 905: atomic_clearbits_int(&p->p_siglist, mask);
! 906: goto out;
! 907: }
! 908: /*
! 909: * When a sleeping process receives a stop
! 910: * signal, process immediately if possible.
! 911: */
! 912: if ((prop & SA_STOP) && action == SIG_DFL) {
! 913: /*
! 914: * If a child holding parent blocked,
! 915: * stopping could cause deadlock.
! 916: */
! 917: if (p->p_flag & P_PPWAIT)
! 918: goto out;
! 919: atomic_clearbits_int(&p->p_siglist, mask);
! 920: p->p_xstat = signum;
! 921: proc_stop(p, 0);
! 922: goto out;
! 923: }
! 924: /*
! 925: * All other (caught or default) signals
! 926: * cause the process to run.
! 927: */
! 928: goto runfast;
! 929: /*NOTREACHED*/
! 930:
! 931: case SSTOP:
! 932: /*
! 933: * If traced process is already stopped,
! 934: * then no further action is necessary.
! 935: */
! 936: if (p->p_flag & P_TRACED)
! 937: goto out;
! 938:
! 939: /*
! 940: * Kill signal always sets processes running.
! 941: */
! 942: if (signum == SIGKILL)
! 943: goto runfast;
! 944:
! 945: if (prop & SA_CONT) {
! 946: /*
! 947: * If SIGCONT is default (or ignored), we continue the
! 948: * process but don't leave the signal in p_siglist, as
! 949: * it has no further action. If SIGCONT is held, we
! 950: * continue the process and leave the signal in
! 951: * p_siglist. If the process catches SIGCONT, let it
! 952: * handle the signal itself. If it isn't waiting on
! 953: * an event, then it goes back to run state.
! 954: * Otherwise, process goes back to sleep state.
! 955: */
! 956: atomic_setbits_int(&p->p_flag, P_CONTINUED);
! 957: wakeparent = 1;
! 958: if (action == SIG_DFL)
! 959: atomic_clearbits_int(&p->p_siglist, mask);
! 960: if (action == SIG_CATCH)
! 961: goto runfast;
! 962: if (p->p_wchan == 0)
! 963: goto run;
! 964: p->p_stat = SSLEEP;
! 965: goto out;
! 966: }
! 967:
! 968: if (prop & SA_STOP) {
! 969: /*
! 970: * Already stopped, don't need to stop again.
! 971: * (If we did the shell could get confused.)
! 972: */
! 973: atomic_clearbits_int(&p->p_siglist, mask);
! 974: goto out;
! 975: }
! 976:
! 977: /*
! 978: * If process is sleeping interruptibly, then simulate a
! 979: * wakeup so that when it is continued, it will be made
! 980: * runnable and can look at the signal. But don't make
! 981: * the process runnable, leave it stopped.
! 982: */
! 983: if (p->p_wchan && p->p_flag & P_SINTR)
! 984: unsleep(p);
! 985: goto out;
! 986:
! 987: case SONPROC:
! 988: signotify(p);
! 989: /* FALLTHROUGH */
! 990: default:
! 991: /*
! 992: * SRUN, SIDL, SZOMB do nothing with the signal,
! 993: * other than kicking ourselves if we are running.
! 994: * It will either never be noticed, or noticed very soon.
! 995: */
! 996: goto out;
! 997: }
! 998: /*NOTREACHED*/
! 999:
! 1000: runfast:
! 1001: /*
! 1002: * Raise priority to at least PUSER.
! 1003: */
! 1004: if (p->p_priority > PUSER)
! 1005: p->p_priority = PUSER;
! 1006: run:
! 1007: setrunnable(p);
! 1008: out:
! 1009: SCHED_UNLOCK(s);
! 1010: if (wakeparent)
! 1011: wakeup(p->p_pptr);
! 1012: }
! 1013:
! 1014: /*
! 1015: * If the current process has received a signal (should be caught or cause
! 1016: * termination, should interrupt current syscall), return the signal number.
! 1017: * Stop signals with default action are processed immediately, then cleared;
! 1018: * they aren't returned. This is checked after each entry to the system for
! 1019: * a syscall or trap (though this can usually be done without calling issignal
! 1020: * by checking the pending signal masks in the CURSIG macro.) The normal call
! 1021: * sequence is
! 1022: *
! 1023: * while (signum = CURSIG(curproc))
! 1024: * postsig(signum);
! 1025: */
! 1026: int
! 1027: issignal(struct proc *p)
! 1028: {
! 1029: int signum, mask, prop;
! 1030: int dolock = (p->p_flag & P_SINTR) == 0;
! 1031: int s;
! 1032:
! 1033: for (;;) {
! 1034: mask = p->p_siglist & ~p->p_sigmask;
! 1035: if (p->p_flag & P_PPWAIT)
! 1036: mask &= ~stopsigmask;
! 1037: if (mask == 0) /* no signal to send */
! 1038: return (0);
! 1039: signum = ffs((long)mask);
! 1040: mask = sigmask(signum);
! 1041: atomic_clearbits_int(&p->p_siglist, mask);
! 1042:
! 1043: /*
! 1044: * We should see pending but ignored signals
! 1045: * only if P_TRACED was on when they were posted.
! 1046: */
! 1047: if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0)
! 1048: continue;
! 1049:
! 1050: if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
! 1051: /*
! 1052: * If traced, always stop, and stay
! 1053: * stopped until released by the debugger.
! 1054: */
! 1055: p->p_xstat = signum;
! 1056:
! 1057: if (dolock)
! 1058: SCHED_LOCK(s);
! 1059: proc_stop(p, 1);
! 1060: if (dolock)
! 1061: SCHED_UNLOCK(s);
! 1062:
! 1063: /*
! 1064: * If we are no longer being traced, or the parent
! 1065: * didn't give us a signal, look for more signals.
! 1066: */
! 1067: if ((p->p_flag & P_TRACED) == 0 || p->p_xstat == 0)
! 1068: continue;
! 1069:
! 1070: /*
! 1071: * If the new signal is being masked, look for other
! 1072: * signals.
! 1073: */
! 1074: signum = p->p_xstat;
! 1075: mask = sigmask(signum);
! 1076: if ((p->p_sigmask & mask) != 0)
! 1077: continue;
! 1078:
! 1079: /* take the signal! */
! 1080: atomic_clearbits_int(&p->p_siglist, mask);
! 1081: }
! 1082:
! 1083: prop = sigprop[signum];
! 1084:
! 1085: /*
! 1086: * Decide whether the signal should be returned.
! 1087: * Return the signal's number, or fall through
! 1088: * to clear it from the pending mask.
! 1089: */
! 1090: switch ((long)p->p_sigacts->ps_sigact[signum]) {
! 1091:
! 1092: case (long)SIG_DFL:
! 1093: /*
! 1094: * Don't take default actions on system processes.
! 1095: */
! 1096: if (p->p_pid <= 1) {
! 1097: #ifdef DIAGNOSTIC
! 1098: /*
! 1099: * Are you sure you want to ignore SIGSEGV
! 1100: * in init? XXX
! 1101: */
! 1102: printf("Process (pid %d) got signal %d\n",
! 1103: p->p_pid, signum);
! 1104: #endif
! 1105: break; /* == ignore */
! 1106: }
! 1107: /*
! 1108: * If there is a pending stop signal to process
! 1109: * with default action, stop here,
! 1110: * then clear the signal. However,
! 1111: * if process is member of an orphaned
! 1112: * process group, ignore tty stop signals.
! 1113: */
! 1114: if (prop & SA_STOP) {
! 1115: if (p->p_flag & P_TRACED ||
! 1116: (p->p_pgrp->pg_jobc == 0 &&
! 1117: prop & SA_TTYSTOP))
! 1118: break; /* == ignore */
! 1119: p->p_xstat = signum;
! 1120: if (dolock)
! 1121: SCHED_LOCK(s);
! 1122: proc_stop(p, 1);
! 1123: if (dolock)
! 1124: SCHED_UNLOCK(s);
! 1125: break;
! 1126: } else if (prop & SA_IGNORE) {
! 1127: /*
! 1128: * Except for SIGCONT, shouldn't get here.
! 1129: * Default action is to ignore; drop it.
! 1130: */
! 1131: break; /* == ignore */
! 1132: } else
! 1133: goto keep;
! 1134: /*NOTREACHED*/
! 1135:
! 1136: case (long)SIG_IGN:
! 1137: /*
! 1138: * Masking above should prevent us ever trying
! 1139: * to take action on an ignored signal other
! 1140: * than SIGCONT, unless process is traced.
! 1141: */
! 1142: if ((prop & SA_CONT) == 0 &&
! 1143: (p->p_flag & P_TRACED) == 0)
! 1144: printf("issignal\n");
! 1145: break; /* == ignore */
! 1146:
! 1147: default:
! 1148: /*
! 1149: * This signal has an action, let
! 1150: * postsig() process it.
! 1151: */
! 1152: goto keep;
! 1153: }
! 1154: }
! 1155: /* NOTREACHED */
! 1156:
! 1157: keep:
! 1158: atomic_setbits_int(&p->p_siglist, mask); /*leave the signal for later */
! 1159: return (signum);
! 1160: }
! 1161:
! 1162: /*
! 1163: * Put the argument process into the stopped state and notify the parent
! 1164: * via wakeup. Signals are handled elsewhere. The process must not be
! 1165: * on the run queue.
! 1166: */
! 1167: void
! 1168: proc_stop(struct proc *p, int sw)
! 1169: {
! 1170: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
! 1171: extern void *softclock_si;
! 1172: #endif
! 1173: #ifdef MULTIPROCESSOR
! 1174: SCHED_ASSERT_LOCKED();
! 1175: #endif
! 1176:
! 1177: p->p_stat = SSTOP;
! 1178: atomic_clearbits_int(&p->p_flag, P_WAITED);
! 1179: atomic_setbits_int(&p->p_flag, P_STOPPED);
! 1180: if (!timeout_pending(&proc_stop_to)) {
! 1181: timeout_add(&proc_stop_to, 0);
! 1182: /*
! 1183: * We need this soft interrupt to be handled fast.
! 1184: * Extra calls to softclock don't hurt.
! 1185: */
! 1186: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
! 1187: softintr_schedule(softclock_si);
! 1188: #else
! 1189: setsoftclock();
! 1190: #endif
! 1191: }
! 1192: if (sw)
! 1193: mi_switch();
! 1194: }
! 1195:
! 1196: /*
! 1197: * Called from a timeout to send signals to the parents of stopped processes.
! 1198: * We can't do this in proc_stop because it's called with nasty locks held
! 1199: * and we would need recursive scheduler lock to deal with that.
! 1200: */
! 1201: void
! 1202: proc_stop_sweep(void *v)
! 1203: {
! 1204: struct proc *p;
! 1205:
! 1206: LIST_FOREACH(p, &allproc, p_list) {
! 1207: if ((p->p_flag & P_STOPPED) == 0)
! 1208: continue;
! 1209: atomic_clearbits_int(&p->p_flag, P_STOPPED);
! 1210:
! 1211: if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
! 1212: psignal(p->p_pptr, SIGCHLD);
! 1213: wakeup(p->p_pptr);
! 1214: }
! 1215: }
! 1216:
! 1217: /*
! 1218: * Take the action for the specified signal
! 1219: * from the current set of pending signals.
! 1220: */
! 1221: void
! 1222: postsig(int signum)
! 1223: {
! 1224: struct proc *p = curproc;
! 1225: struct sigacts *ps = p->p_sigacts;
! 1226: sig_t action;
! 1227: u_long code;
! 1228: int mask, returnmask;
! 1229: union sigval sigval;
! 1230: int s, type;
! 1231:
! 1232: #ifdef DIAGNOSTIC
! 1233: if (signum == 0)
! 1234: panic("postsig");
! 1235: #endif
! 1236:
! 1237: KERNEL_PROC_LOCK(p);
! 1238:
! 1239: mask = sigmask(signum);
! 1240: atomic_clearbits_int(&p->p_siglist, mask);
! 1241: action = ps->ps_sigact[signum];
! 1242: sigval.sival_ptr = 0;
! 1243: type = SI_USER;
! 1244:
! 1245: if (ps->ps_sig != signum) {
! 1246: code = 0;
! 1247: type = SI_USER;
! 1248: sigval.sival_ptr = 0;
! 1249: } else {
! 1250: code = ps->ps_code;
! 1251: type = ps->ps_type;
! 1252: sigval = ps->ps_sigval;
! 1253: }
! 1254:
! 1255: #ifdef KTRACE
! 1256: if (KTRPOINT(p, KTR_PSIG)) {
! 1257: siginfo_t si;
! 1258:
! 1259: initsiginfo(&si, signum, code, type, sigval);
! 1260: ktrpsig(p, signum, action, ps->ps_flags & SAS_OLDMASK ?
! 1261: ps->ps_oldmask : p->p_sigmask, type, &si);
! 1262: }
! 1263: #endif
! 1264: if (action == SIG_DFL) {
! 1265: /*
! 1266: * Default action, where the default is to kill
! 1267: * the process. (Other cases were ignored above.)
! 1268: */
! 1269: sigexit(p, signum);
! 1270: /* NOTREACHED */
! 1271: } else {
! 1272: /*
! 1273: * If we get here, the signal must be caught.
! 1274: */
! 1275: #ifdef DIAGNOSTIC
! 1276: if (action == SIG_IGN || (p->p_sigmask & mask))
! 1277: panic("postsig action");
! 1278: #endif
! 1279: /*
! 1280: * Set the new mask value and also defer further
! 1281: * occurences of this signal.
! 1282: *
! 1283: * Special case: user has done a sigpause. Here the
! 1284: * current mask is not of interest, but rather the
! 1285: * mask from before the sigpause is what we want
! 1286: * restored after the signal processing is completed.
! 1287: */
! 1288: #ifdef MULTIPROCESSOR
! 1289: s = splsched();
! 1290: #else
! 1291: s = splhigh();
! 1292: #endif
! 1293: if (ps->ps_flags & SAS_OLDMASK) {
! 1294: returnmask = ps->ps_oldmask;
! 1295: ps->ps_flags &= ~SAS_OLDMASK;
! 1296: } else
! 1297: returnmask = p->p_sigmask;
! 1298: p->p_sigmask |= ps->ps_catchmask[signum];
! 1299: if ((ps->ps_sigreset & mask) != 0) {
! 1300: p->p_sigcatch &= ~mask;
! 1301: if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
! 1302: p->p_sigignore |= mask;
! 1303: ps->ps_sigact[signum] = SIG_DFL;
! 1304: }
! 1305: splx(s);
! 1306: p->p_stats->p_ru.ru_nsignals++;
! 1307: if (ps->ps_sig == signum) {
! 1308: ps->ps_sig = 0;
! 1309: ps->ps_code = 0;
! 1310: ps->ps_type = SI_USER;
! 1311: ps->ps_sigval.sival_ptr = NULL;
! 1312: }
! 1313:
! 1314: (*p->p_emul->e_sendsig)(action, signum, returnmask, code,
! 1315: type, sigval);
! 1316: }
! 1317:
! 1318: KERNEL_PROC_UNLOCK(p);
! 1319: }
! 1320:
! 1321: /*
! 1322: * Force the current process to exit with the specified signal, dumping core
! 1323: * if appropriate. We bypass the normal tests for masked and caught signals,
! 1324: * allowing unrecoverable failures to terminate the process without changing
! 1325: * signal state. Mark the accounting record with the signal termination.
! 1326: * If dumping core, save the signal number for the debugger. Calls exit and
! 1327: * does not return.
! 1328: */
! 1329: void
! 1330: sigexit(struct proc *p, int signum)
! 1331: {
! 1332: /* Mark process as going away */
! 1333: atomic_setbits_int(&p->p_flag, P_WEXIT);
! 1334:
! 1335: p->p_acflag |= AXSIG;
! 1336: if (sigprop[signum] & SA_CORE) {
! 1337: p->p_sigacts->ps_sig = signum;
! 1338: if (coredump(p) == 0)
! 1339: signum |= WCOREFLAG;
! 1340: }
! 1341: exit1(p, W_EXITCODE(0, signum), EXIT_NORMAL);
! 1342: /* NOTREACHED */
! 1343: }
! 1344:
! 1345: int nosuidcoredump = 1;
! 1346:
! 1347: /*
! 1348: * Dump core, into a file named "progname.core", unless the process was
! 1349: * setuid/setgid.
! 1350: */
! 1351: int
! 1352: coredump(struct proc *p)
! 1353: {
! 1354: struct vnode *vp;
! 1355: struct ucred *cred = p->p_ucred;
! 1356: struct vmspace *vm = p->p_vmspace;
! 1357: struct nameidata nd;
! 1358: struct vattr vattr;
! 1359: int error, error1, len;
! 1360: char name[sizeof("/var/crash/") + MAXCOMLEN + sizeof(".core")];
! 1361: char *dir = "";
! 1362: struct core core;
! 1363:
! 1364: /*
! 1365: * Don't dump if not root and the process has used set user or
! 1366: * group privileges, unless the nosuidcoredump sysctl is set to 2,
! 1367: * in which case dumps are put into /var/crash/.
! 1368: */
! 1369: if (((p->p_flag & P_SUGID) && (error = suser(p, 0))) ||
! 1370: ((p->p_flag & P_SUGID) && nosuidcoredump)) {
! 1371: if (nosuidcoredump == 2)
! 1372: dir = "/var/crash/";
! 1373: else
! 1374: return (EPERM);
! 1375: }
! 1376:
! 1377: /* Don't dump if will exceed file size limit. */
! 1378: if (USPACE + ctob(vm->vm_dsize + vm->vm_ssize) >=
! 1379: p->p_rlimit[RLIMIT_CORE].rlim_cur)
! 1380: return (EFBIG);
! 1381:
! 1382: len = snprintf(name, sizeof(name), "%s%s.core", dir, p->p_comm);
! 1383: if (len >= sizeof(name))
! 1384: return (EACCES);
! 1385:
! 1386: /*
! 1387: * ... but actually write it as UID
! 1388: */
! 1389: cred = crdup(cred);
! 1390: cred->cr_uid = p->p_cred->p_ruid;
! 1391: cred->cr_gid = p->p_cred->p_rgid;
! 1392:
! 1393: NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
! 1394:
! 1395: error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
! 1396:
! 1397: if (error) {
! 1398: crfree(cred);
! 1399: return (error);
! 1400: }
! 1401:
! 1402: /*
! 1403: * Don't dump to non-regular files, files with links, or files
! 1404: * owned by someone else.
! 1405: */
! 1406: vp = nd.ni_vp;
! 1407: if ((error = VOP_GETATTR(vp, &vattr, cred, p)) != 0)
! 1408: goto out;
! 1409: /* Don't dump to non-regular files or files with links. */
! 1410: if (vp->v_type != VREG || vattr.va_nlink != 1 ||
! 1411: vattr.va_mode & ((VREAD | VWRITE) >> 3 | (VREAD | VWRITE) >> 6)) {
! 1412: error = EACCES;
! 1413: goto out;
! 1414: }
! 1415: VATTR_NULL(&vattr);
! 1416: vattr.va_size = 0;
! 1417: VOP_SETATTR(vp, &vattr, cred, p);
! 1418: p->p_acflag |= ACORE;
! 1419: bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
! 1420: fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
! 1421:
! 1422: core.c_midmag = 0;
! 1423: strlcpy(core.c_name, p->p_comm, sizeof(core.c_name));
! 1424: core.c_nseg = 0;
! 1425: core.c_signo = p->p_sigacts->ps_sig;
! 1426: core.c_ucode = p->p_sigacts->ps_code;
! 1427: core.c_cpusize = 0;
! 1428: core.c_tsize = (u_long)ctob(vm->vm_tsize);
! 1429: core.c_dsize = (u_long)ctob(vm->vm_dsize);
! 1430: core.c_ssize = (u_long)round_page(ctob(vm->vm_ssize));
! 1431: error = cpu_coredump(p, vp, cred, &core);
! 1432: if (error)
! 1433: goto out;
! 1434: /*
! 1435: * uvm_coredump() spits out all appropriate segments.
! 1436: * All that's left to do is to write the core header.
! 1437: */
! 1438: error = uvm_coredump(p, vp, cred, &core);
! 1439: if (error)
! 1440: goto out;
! 1441: error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&core,
! 1442: (int)core.c_hdrsize, (off_t)0,
! 1443: UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p);
! 1444: out:
! 1445: VOP_UNLOCK(vp, 0, p);
! 1446: error1 = vn_close(vp, FWRITE, cred, p);
! 1447: crfree(cred);
! 1448: if (error == 0)
! 1449: error = error1;
! 1450: return (error);
! 1451: }
! 1452:
! 1453: /*
! 1454: * Nonexistent system call-- signal process (may want to handle it).
! 1455: * Flag error in case process won't see signal immediately (blocked or ignored).
! 1456: */
! 1457: /* ARGSUSED */
! 1458: int
! 1459: sys_nosys(struct proc *p, void *v, register_t *retval)
! 1460: {
! 1461:
! 1462: psignal(p, SIGSYS);
! 1463: return (ENOSYS);
! 1464: }
! 1465:
! 1466: #ifdef RTHREADS
! 1467: int
! 1468: sys_thrsigdivert(struct proc *p, void *v, register_t *retval)
! 1469: {
! 1470: struct sys_thrsigdivert_args *uap = v;
! 1471:
! 1472: p->p_sigdivert = SCARG(uap, sigmask);
! 1473:
! 1474: return (0);
! 1475: }
! 1476: #endif
! 1477:
! 1478: void
! 1479: initsiginfo(siginfo_t *si, int sig, u_long code, int type, union sigval val)
! 1480: {
! 1481: bzero(si, sizeof *si);
! 1482:
! 1483: si->si_signo = sig;
! 1484: si->si_code = type;
! 1485: if (type == SI_USER) {
! 1486: si->si_value = val;
! 1487: } else {
! 1488: switch (sig) {
! 1489: case SIGSEGV:
! 1490: case SIGILL:
! 1491: case SIGBUS:
! 1492: case SIGFPE:
! 1493: si->si_addr = val.sival_ptr;
! 1494: si->si_trapno = code;
! 1495: break;
! 1496: case SIGXFSZ:
! 1497: break;
! 1498: }
! 1499: }
! 1500: }
! 1501:
! 1502: int
! 1503: filt_sigattach(struct knote *kn)
! 1504: {
! 1505: struct proc *p = curproc;
! 1506:
! 1507: kn->kn_ptr.p_proc = p;
! 1508: kn->kn_flags |= EV_CLEAR; /* automatically set */
! 1509:
! 1510: /* XXX lock the proc here while adding to the list? */
! 1511: SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext);
! 1512:
! 1513: return (0);
! 1514: }
! 1515:
! 1516: void
! 1517: filt_sigdetach(struct knote *kn)
! 1518: {
! 1519: struct proc *p = kn->kn_ptr.p_proc;
! 1520:
! 1521: SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext);
! 1522: }
! 1523:
! 1524: /*
! 1525: * signal knotes are shared with proc knotes, so we apply a mask to
! 1526: * the hint in order to differentiate them from process hints. This
! 1527: * could be avoided by using a signal-specific knote list, but probably
! 1528: * isn't worth the trouble.
! 1529: */
! 1530: int
! 1531: filt_signal(struct knote *kn, long hint)
! 1532: {
! 1533:
! 1534: if (hint & NOTE_SIGNAL) {
! 1535: hint &= ~NOTE_SIGNAL;
! 1536:
! 1537: if (kn->kn_id == hint)
! 1538: kn->kn_data++;
! 1539: }
! 1540: return (kn->kn_data != 0);
! 1541: }
CVSweb