|
|
1.1 ! root 1: /* sig.c 4.12 81/07/03 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../h/systm.h" ! 5: #include "../h/dir.h" ! 6: #include "../h/user.h" ! 7: #include "../h/proc.h" ! 8: #include "../h/inode.h" ! 9: #include "../h/reg.h" ! 10: #include "../h/text.h" ! 11: #include "../h/seg.h" ! 12: #include "../h/mtpr.h" ! 13: #include "../h/pte.h" ! 14: #include "../h/psl.h" ! 15: #include "../h/vm.h" ! 16: #include "../h/buf.h" ! 17: #include "../h/conf.h" ! 18: #include "../h/vlimit.h" ! 19: ! 20: /* ! 21: * Send the specified signal to ! 22: * all processes with 'pgrp' as ! 23: * process group. ! 24: * Called by tty.c for quits and ! 25: * interrupts. ! 26: */ ! 27: gsignal(pgrp, sig) ! 28: register pgrp; ! 29: { ! 30: register struct proc *p; ! 31: ! 32: if(pgrp == 0) ! 33: return; ! 34: for(p = proc; p < procNPROC; p++) ! 35: if(p->p_pgrp == pgrp) ! 36: psignal(p, sig); ! 37: } ! 38: ! 39: /* ! 40: * Send the specified signal to ! 41: * the specified process. ! 42: */ ! 43: psignal(p, sig) ! 44: register struct proc *p; ! 45: register int sig; ! 46: { ! 47: register s; ! 48: register int (*action)(); ! 49: long sigmask; ! 50: ! 51: if((unsigned)sig >= NSIG) ! 52: return; ! 53: sigmask = (1L << (sig-1)); ! 54: ! 55: /* ! 56: * If proc is traced, always give parent a chance. ! 57: * Otherwise get the signal action from the bits in the proc table. ! 58: */ ! 59: if (p->p_flag & STRC) ! 60: action = SIG_DFL; ! 61: else { ! 62: s = (p->p_siga1&sigmask) != 0; ! 63: s <<= 1; ! 64: s |= (p->p_siga0&sigmask) != 0; ! 65: action = (int(*)())s; ! 66: /* ! 67: * If the signal is ignored, we forget about it immediately. ! 68: */ ! 69: if (action == SIG_IGN) ! 70: return; ! 71: } ! 72: #define mask(sig) (1<<(sig-1)) ! 73: #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) ! 74: if (sig) { ! 75: p->p_sig |= sigmask; ! 76: switch (sig) { ! 77: ! 78: case SIGTERM: ! 79: if ((p->p_flag&STRC) != 0 || action != SIG_DFL) ! 80: break; ! 81: /* fall into ... */ ! 82: ! 83: case SIGKILL: ! 84: if (p->p_nice > NZERO) ! 85: p->p_nice = NZERO; ! 86: break; ! 87: ! 88: case SIGCONT: ! 89: p->p_sig &= ~stops; ! 90: break; ! 91: ! 92: case SIGSTOP: ! 93: case SIGTSTP: ! 94: case SIGTTIN: ! 95: case SIGTTOU: ! 96: p->p_sig &= ~mask(SIGCONT); ! 97: break; ! 98: } ! 99: } ! 100: #undef mask ! 101: #undef stops ! 102: /* ! 103: * Defer further processing for signals which are held. ! 104: */ ! 105: if (action == SIG_HOLD) ! 106: return; ! 107: s = spl6(); ! 108: switch (p->p_stat) { ! 109: ! 110: case SSLEEP: ! 111: /* ! 112: * If process is sleeping at negative priority ! 113: * we can't interrupt the sleep... the signal will ! 114: * be noticed when the process returns through ! 115: * trap() or syscall(). ! 116: */ ! 117: if (p->p_pri <= PZERO) ! 118: goto out; ! 119: /* ! 120: * Process is sleeping and traced... make it runnable ! 121: * so it can discover the signal in issig() and stop ! 122: * for the parent. ! 123: */ ! 124: if (p->p_flag&STRC) ! 125: goto run; ! 126: switch (sig) { ! 127: ! 128: case SIGSTOP: ! 129: case SIGTSTP: ! 130: case SIGTTIN: ! 131: case SIGTTOU: ! 132: /* ! 133: * These are the signals which by default ! 134: * stop a process. ! 135: */ ! 136: if (action != SIG_DFL) ! 137: goto run; ! 138: /* ! 139: * Don't clog system with children of init ! 140: * stopped from the keyboard. ! 141: */ ! 142: if (sig != SIGSTOP && p->p_pptr == &proc[1]) { ! 143: psignal(p, SIGKILL); ! 144: p->p_sig &= ~sigmask; ! 145: splx(s); ! 146: return; ! 147: } ! 148: /* ! 149: * If a child in vfork(), stopping could ! 150: * cause deadlock. ! 151: */ ! 152: if (p->p_flag&SVFORK) ! 153: goto out; ! 154: p->p_sig &= ~sigmask; ! 155: p->p_cursig = sig; ! 156: stop(p); ! 157: goto out; ! 158: ! 159: case SIGTINT: ! 160: case SIGCHLD: ! 161: /* ! 162: * These signals are special in that they ! 163: * don't get propogated... if the process ! 164: * isn't interested, forget it. ! 165: */ ! 166: if (action != SIG_DFL) ! 167: goto run; ! 168: p->p_sig &= ~sigmask; /* take it away */ ! 169: goto out; ! 170: ! 171: default: ! 172: /* ! 173: * All other signals cause the process to run ! 174: */ ! 175: goto run; ! 176: } ! 177: /*NOTREACHED*/ ! 178: ! 179: case SSTOP: ! 180: /* ! 181: * If traced process is already stopped, ! 182: * then no further action is necessary, ! 183: * except to guarantee a sure SIGKILL and ! 184: * prevent multiple SIGSTOP's. ! 185: */ ! 186: if ((p->p_flag&STRC) && sig != SIGKILL && sig != SIGSTOP) ! 187: goto out; ! 188: switch (sig) { ! 189: ! 190: case SIGKILL: ! 191: /* ! 192: * Kill signal always sets processes running. ! 193: */ ! 194: goto run; ! 195: ! 196: case SIGCONT: ! 197: /* ! 198: * If the process catches SIGCONT, let it handle ! 199: * the signal itself. If it isn't waiting on ! 200: * an event, then it goes back to run state. ! 201: * Otherwise, process goes back to sleep state. ! 202: */ ! 203: if (action != SIG_DFL || p->p_wchan == 0) ! 204: goto run; ! 205: p->p_stat = SSLEEP; ! 206: goto out; ! 207: ! 208: case SIGSTOP: ! 209: case SIGTSTP: ! 210: case SIGTTIN: ! 211: case SIGTTOU: ! 212: /* ! 213: * Already stopped, don't need to stop again. ! 214: * (If we did the shell could get confused.) ! 215: */ ! 216: p->p_sig &= ~sigmask; /* take it away */ ! 217: goto out; ! 218: ! 219: default: ! 220: /* ! 221: * If process is sleeping interruptibly, then ! 222: * unstick it so that when it is continued ! 223: * it can look at the signal. ! 224: * But don't setrun the process as its not to ! 225: * be unstopped by the signal alone. ! 226: */ ! 227: if (p->p_wchan && p->p_pri > PZERO) ! 228: unsleep(p); ! 229: goto out; ! 230: } ! 231: /*NOTREACHED*/ ! 232: ! 233: default: ! 234: /* ! 235: * SRUN, SIDL, SZOMB do nothing with the signal, ! 236: * other than kicking ourselves if we are running. ! 237: * It will either never be noticed, or noticed very soon. ! 238: */ ! 239: if (p == u.u_procp && !noproc) ! 240: aston(); ! 241: goto out; ! 242: } ! 243: /*NOTREACHED*/ ! 244: run: ! 245: /* ! 246: * Raise priority to at least PUSER. ! 247: */ ! 248: if (p->p_pri > PUSER) ! 249: if ((p != u.u_procp || noproc) && p->p_stat == SRUN && ! 250: (p->p_flag & SLOAD)) { ! 251: remrq(p); ! 252: p->p_pri = PUSER; ! 253: setrq(p); ! 254: } else ! 255: p->p_pri = PUSER; ! 256: setrun(p); ! 257: out: ! 258: splx(s); ! 259: } ! 260: ! 261: /* ! 262: * Returns true if the current ! 263: * process has a signal to process. ! 264: * The signal to process is put in p_cursig. ! 265: * This is asked at least once each time a process enters the ! 266: * system (though this can usually be done without actually ! 267: * calling issig by checking the pending signal masks.) ! 268: * A signal does not do anything ! 269: * directly to a process; it sets ! 270: * a flag that asks the process to ! 271: * do something to itself. ! 272: */ ! 273: #define bit(a) (1<<(a-1)) ! 274: issig() ! 275: { ! 276: register struct proc *p = u.u_procp; ! 277: register int sig; ! 278: long sigbits, sigmask, trmask; ! 279: ! 280: for (;;) { ! 281: sigbits = p->p_sig; ! 282: if ((p->p_flag&STRC) == 0) ! 283: sigbits &= ~p->p_ignsig; ! 284: if (p->p_flag&SVFORK) ! 285: sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); ! 286: if (sigbits == 0) ! 287: break; ! 288: sig = (sigbits & bit(SIGKILL)) ? SIGKILL : ffs(sigbits); ! 289: ! 290: sigmask = 1L << (sig-1); ! 291: p->p_sig &= ~sigmask; /* take the signal! */ ! 292: p->p_cursig = sig; ! 293: ! 294: trmask = bit(SIGSTOP); /* SIGSTOP always traced */ ! 295: if (p->p_flag&STRC) { ! 296: register struct proc *pp = p; ! 297: do if (pp->p_trace) { ! 298: trmask |= pp->p_trace->i_un.i_sigmask; ! 299: break; ! 300: } while ((pp = pp->p_pptr) && pp->p_flag&STRC); ! 301: } ! 302: trmask &= sigmask & (~bit(SIGKILL)); ! 303: ! 304: if (trmask) { ! 305: /* ! 306: * If traced, always stop. ! 307: */ ! 308: stop(p); ! 309: swtch(); ! 310: /* ! 311: * If debugger wants us to take the signal, ! 312: * then it will leave it in p->p_cursig; ! 313: * otherwise we just look for signals again. ! 314: */ ! 315: if ((sig = p->p_cursig) == 0) ! 316: continue; ! 317: } ! 318: switch ((int)u.u_signal[sig]) { ! 319: ! 320: case (int)SIG_DFL: ! 321: /* ! 322: * Don't take default actions on system processes. ! 323: */ ! 324: if (p <= &proc[2]) ! 325: break; ! 326: switch (sig) { ! 327: ! 328: case SIGTSTP: ! 329: case SIGTTIN: ! 330: case SIGTTOU: ! 331: /* ! 332: * Children of init aren't allowed to stop ! 333: * on signals from the keyboard. ! 334: */ ! 335: if (p->p_pptr == &proc[1]) { ! 336: psignal(p, SIGKILL); ! 337: continue; ! 338: } ! 339: /* fall into ... */ ! 340: ! 341: case SIGSTOP: ! 342: if (trmask) ! 343: continue; ! 344: stop(p); ! 345: swtch(); ! 346: continue; ! 347: ! 348: case SIGTINT: ! 349: case SIGCONT: ! 350: case SIGCHLD: ! 351: /* ! 352: * These signals are normally not ! 353: * sent if the action is the default. ! 354: * This can happen only if you reset the ! 355: * signal action from an action which was ! 356: * not deferred to SIG_DFL before the ! 357: * system gets a chance to post the signal. ! 358: */ ! 359: continue; /* == ignore */ ! 360: ! 361: default: ! 362: goto send; ! 363: } ! 364: /*NOTREACHED*/ ! 365: ! 366: case (int)SIG_HOLD: ! 367: case (int)SIG_IGN: ! 368: /* ! 369: * Masking above should prevent us ! 370: * ever trying to take action on a held ! 371: * or ignored signal, unless process is traced. ! 372: */ ! 373: if ((p->p_flag&STRC) == 0) ! 374: printf("issig\n"); ! 375: continue; ! 376: ! 377: default: ! 378: /* ! 379: * This signal has an action, let ! 380: * psig process it. ! 381: */ ! 382: goto send; ! 383: } ! 384: /*NOTREACHED*/ ! 385: } ! 386: /* ! 387: * Didn't find a signal to send. ! 388: */ ! 389: p->p_cursig = 0; ! 390: return (0); ! 391: ! 392: send: ! 393: /* ! 394: * Let psig process the signal. ! 395: */ ! 396: return (sig); ! 397: } ! 398: ! 399: #ifndef vax ! 400: ffs(mask) ! 401: register long mask; ! 402: { ! 403: register int i; ! 404: ! 405: for(i=1; i<NSIG; i++) { ! 406: if(mask & 1) ! 407: return(i); ! 408: mask >>= 1; ! 409: } ! 410: return(0); ! 411: } ! 412: #endif ! 413: ! 414: /* ! 415: * Put the argument process into the stopped ! 416: * state and notify the parent via wakeup and/or signal. ! 417: */ ! 418: stop(p) ! 419: register struct proc *p; ! 420: { ! 421: ! 422: p->p_stat = SSTOP; ! 423: p->p_flag &= ~SWTED; ! 424: wakeup((caddr_t)p->p_pptr); ! 425: wakeup((caddr_t)p->p_trace); ! 426: /* ! 427: * Avoid sending signal to parent if process is traced ! 428: */ ! 429: if (p->p_flag&STRC) ! 430: return; ! 431: psignal(p->p_pptr, SIGCHLD); ! 432: } ! 433: ! 434: /* ! 435: * Perform the action specified by ! 436: * the current signal. ! 437: * The usual sequence is: ! 438: * if(issig()) ! 439: * psig(); ! 440: * The signal bit has already been cleared by issig, ! 441: * and the current signal number stored in p->p_cursig. ! 442: */ ! 443: psig() ! 444: { ! 445: register struct proc *rp = u.u_procp; ! 446: register int n = rp->p_cursig; ! 447: long sigmask = 1L << (n-1); ! 448: register int (*action)(); ! 449: ! 450: if (rp->p_cursig == 0) ! 451: panic("psig"); ! 452: action = u.u_signal[n]; ! 453: if (action != SIG_DFL) { ! 454: if (action == SIG_IGN || action == SIG_HOLD) ! 455: panic("psig action"); ! 456: u.u_error = 0; ! 457: if(n != SIGILL && n != SIGTRAP) ! 458: u.u_signal[n] = 0; ! 459: /* ! 460: * If this catch value indicates automatic holding of ! 461: * subsequent signals, set the hold value. ! 462: */ ! 463: if (SIGISDEFER(action)) { ! 464: (void) spl6(); ! 465: if ((int)SIG_HOLD & 1) ! 466: rp->p_siga0 |= sigmask; ! 467: else ! 468: rp->p_siga0 &= ~sigmask; ! 469: if ((int)SIG_HOLD & 2) ! 470: rp->p_siga1 |= sigmask; ! 471: else ! 472: rp->p_siga1 &= ~sigmask; ! 473: u.u_signal[n] = SIG_HOLD; ! 474: (void) spl0(); ! 475: action = SIGUNDEFER(action); ! 476: } ! 477: sendsig(action, n); ! 478: rp->p_cursig = 0; ! 479: return; ! 480: } ! 481: switch (n) { ! 482: ! 483: case SIGILL: ! 484: case SIGIOT: ! 485: case SIGBUS: ! 486: case SIGQUIT: ! 487: case SIGTRAP: ! 488: case SIGEMT: ! 489: case SIGFPE: ! 490: case SIGSEGV: ! 491: case SIGSYS: ! 492: u.u_arg[0] = n; ! 493: if(core()) ! 494: n += 0200; ! 495: } ! 496: exit(n); ! 497: } ! 498: ! 499: #ifdef unneeded ! 500: int corestop = 0; ! 501: #endif ! 502: /* ! 503: * Create a core image on the file "core" ! 504: * If you are looking for protection glitches, ! 505: * there are probably a wealth of them here ! 506: * when this occurs to a suid command. ! 507: * ! 508: * It writes UPAGES block of the ! 509: * user.h area followed by the entire ! 510: * data+stack segments. ! 511: */ ! 512: core() ! 513: { ! 514: register struct inode *ip; ! 515: extern schar(); ! 516: struct argnamei nmarg; struct proc coreproc; ! 517: ! 518: if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE]) ! 519: return (0); ! 520: coreproc = *u.u_procp; ! 521: u.u_stack[0] = (int)&coreproc; ! 522: u.u_error = 0; ! 523: u.u_uid = u.u_ruid; ! 524: u.u_gid = u.u_rgid; ! 525: u.u_dirp = "core"; ! 526: nmarg = nilargnamei; ! 527: nmarg.flag = NI_CREAT; ! 528: nmarg.mode = 0666; ! 529: ip = namei(schar, &nmarg, 1); ! 530: if(ip == NULL) ! 531: return(0); ! 532: if(!access(ip, IWRITE) && ! 533: (ip->i_mode&IFMT) == IFREG && ip->i_nlink==1) { ! 534: (*fstypsw[ip->i_fstyp].t_trunc)(ip); ! 535: u.u_offset = 0; ! 536: u.u_base = (caddr_t)&u; ! 537: u.u_count = ctob(UPAGES); ! 538: u.u_segflg = 1; ! 539: writei(ip); ! 540: u.u_base = (char *)ctob(u.u_tsize); ! 541: u.u_count = ctob(u.u_dsize); ! 542: u.u_segflg = 0; ! 543: writei(ip); ! 544: u.u_base = (char *)(USRSTACK - ctob(u.u_ssize)); ! 545: u.u_count = ctob(u.u_ssize); ! 546: writei(ip); ! 547: } else ! 548: u.u_error = EFAULT; ! 549: iput(ip); ! 550: return(u.u_error==0); ! 551: } ! 552: ! 553: /* ! 554: * grow the stack to include the SP ! 555: * true return if successful. ! 556: */ ! 557: grow(sp) ! 558: unsigned sp; ! 559: { ! 560: register si; ! 561: ! 562: if(sp >= USRSTACK-ctob(u.u_ssize)) ! 563: return(0); ! 564: si = clrnd(btoc((USRSTACK-sp)) - u.u_ssize + SINCR); ! 565: if (ctob(u.u_ssize+si) > u.u_limit[LIM_STACK]) ! 566: return(0); ! 567: if (chksize(u.u_tsize, u.u_dsize, u.u_ssize+si)) ! 568: return(0); ! 569: if (swpexpand(u.u_dsize, u.u_ssize+si, &u.u_dmap, &u.u_smap)==0) ! 570: return(0); ! 571: ! 572: expand(si, P1BR); ! 573: return(1); ! 574: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.