1*7421Sroot /* kern_sig.c 5.1 82/07/15 */ 2*7421Sroot 3*7421Sroot #include "../h/param.h" 4*7421Sroot #include "../h/systm.h" 5*7421Sroot #include "../h/dir.h" 6*7421Sroot #include "../h/user.h" 7*7421Sroot #include "../h/reg.h" 8*7421Sroot #include "../h/inode.h" 9*7421Sroot #include "../h/proc.h" 10*7421Sroot #include "../h/clock.h" 11*7421Sroot #include "../h/mtpr.h" 12*7421Sroot #include "../h/timeb.h" 13*7421Sroot #include "../h/times.h" 14*7421Sroot #include "../h/conf.h" 15*7421Sroot #include "../h/buf.h" 16*7421Sroot #include "../h/mount.h" 17*7421Sroot #include "../h/text.h" 18*7421Sroot #include "../h/seg.h" 19*7421Sroot #include "../h/pte.h" 20*7421Sroot #include "../h/psl.h" 21*7421Sroot #include "../h/vm.h" 22*7421Sroot #include "../h/vlimit.h" 23*7421Sroot #include "../h/acct.h" 24*7421Sroot 25*7421Sroot ssig() 26*7421Sroot { 27*7421Sroot register int (*f)(); 28*7421Sroot struct a { 29*7421Sroot int signo; 30*7421Sroot int (*fun)(); 31*7421Sroot } *uap; 32*7421Sroot register struct proc *p = u.u_procp; 33*7421Sroot register a; 34*7421Sroot long sigmask; 35*7421Sroot 36*7421Sroot uap = (struct a *)u.u_ap; 37*7421Sroot a = uap->signo & SIGNUMMASK; 38*7421Sroot f = uap->fun; 39*7421Sroot if (a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP || 40*7421Sroot a==SIGCONT && (f == SIG_IGN || f == SIG_HOLD)) { 41*7421Sroot u.u_error = EINVAL; 42*7421Sroot return; 43*7421Sroot } 44*7421Sroot if ((uap->signo &~ SIGNUMMASK) || (f != SIG_DFL && f != SIG_IGN && 45*7421Sroot SIGISDEFER(f))) 46*7421Sroot u.u_procp->p_flag |= SNUSIG; 47*7421Sroot /* 48*7421Sroot * Don't clobber registers if we are to simulate 49*7421Sroot * a ret+rti. 50*7421Sroot */ 51*7421Sroot if ((uap->signo&SIGDORTI) == 0) 52*7421Sroot u.u_r.r_val1 = (int)u.u_signal[a]; 53*7421Sroot /* 54*7421Sroot * Change setting atomically. 55*7421Sroot */ 56*7421Sroot (void) spl6(); 57*7421Sroot sigmask = 1L << (a-1); 58*7421Sroot if (u.u_signal[a] == SIG_IGN) 59*7421Sroot p->p_sig &= ~sigmask; /* never to be seen again */ 60*7421Sroot u.u_signal[a] = f; 61*7421Sroot if (f != SIG_DFL && f != SIG_IGN && f != SIG_HOLD) 62*7421Sroot f = SIG_CATCH; 63*7421Sroot if ((int)f & 1) 64*7421Sroot p->p_siga0 |= sigmask; 65*7421Sroot else 66*7421Sroot p->p_siga0 &= ~sigmask; 67*7421Sroot if ((int)f & 2) 68*7421Sroot p->p_siga1 |= sigmask; 69*7421Sroot else 70*7421Sroot p->p_siga1 &= ~sigmask; 71*7421Sroot (void) spl0(); 72*7421Sroot /* 73*7421Sroot * Now handle options. 74*7421Sroot */ 75*7421Sroot if (uap->signo & SIGDOPAUSE) { 76*7421Sroot /* 77*7421Sroot * Simulate a PDP11 style wait instrution which 78*7421Sroot * atomically lowers priority, enables interrupts 79*7421Sroot * and hangs. 80*7421Sroot */ 81*7421Sroot pause(); 82*7421Sroot /*NOTREACHED*/ 83*7421Sroot } 84*7421Sroot if (uap->signo & SIGDORTI) 85*7421Sroot u.u_eosys = SIMULATERTI; 86*7421Sroot } 87*7421Sroot 88*7421Sroot kill() 89*7421Sroot { 90*7421Sroot register struct proc *p; 91*7421Sroot register a, sig; 92*7421Sroot register struct a { 93*7421Sroot int pid; 94*7421Sroot int signo; 95*7421Sroot } *uap; 96*7421Sroot int f, priv; 97*7421Sroot 98*7421Sroot uap = (struct a *)u.u_ap; 99*7421Sroot f = 0; 100*7421Sroot a = uap->pid; 101*7421Sroot priv = 0; 102*7421Sroot sig = uap->signo; 103*7421Sroot if (sig < 0) 104*7421Sroot /* 105*7421Sroot * A negative signal means send to process group. 106*7421Sroot */ 107*7421Sroot uap->signo = -uap->signo; 108*7421Sroot if (uap->signo == 0 || uap->signo > NSIG) { 109*7421Sroot u.u_error = EINVAL; 110*7421Sroot return; 111*7421Sroot } 112*7421Sroot if (a > 0 && sig > 0) { 113*7421Sroot p = pfind(a); 114*7421Sroot if (p == 0 || u.u_uid && u.u_uid != p->p_uid) { 115*7421Sroot u.u_error = ESRCH; 116*7421Sroot return; 117*7421Sroot } 118*7421Sroot psignal(p, uap->signo); 119*7421Sroot return; 120*7421Sroot } 121*7421Sroot if (a==-1 && u.u_uid==0) { 122*7421Sroot priv++; 123*7421Sroot a = 0; 124*7421Sroot sig = -1; /* like sending to pgrp */ 125*7421Sroot } else if (a==0) { 126*7421Sroot /* 127*7421Sroot * Zero process id means send to my process group. 128*7421Sroot */ 129*7421Sroot sig = -1; 130*7421Sroot a = u.u_procp->p_pgrp; 131*7421Sroot if (a == 0) { 132*7421Sroot u.u_error = EINVAL; 133*7421Sroot return; 134*7421Sroot } 135*7421Sroot } 136*7421Sroot for(p = proc; p < procNPROC; p++) { 137*7421Sroot if (p->p_stat == NULL) 138*7421Sroot continue; 139*7421Sroot if (sig > 0) { 140*7421Sroot if (p->p_pid != a) 141*7421Sroot continue; 142*7421Sroot } else if (p->p_pgrp!=a && priv==0 || p->p_ppid==0 || 143*7421Sroot (p->p_flag&SSYS) || (priv && p==u.u_procp)) 144*7421Sroot continue; 145*7421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 146*7421Sroot (uap->signo != SIGCONT || !inferior(p))) 147*7421Sroot continue; 148*7421Sroot f++; 149*7421Sroot psignal(p, uap->signo); 150*7421Sroot } 151*7421Sroot if (f == 0) 152*7421Sroot u.u_error = ESRCH; 153*7421Sroot } 154*7421Sroot 155*7421Sroot /* 156*7421Sroot * Priority for tracing 157*7421Sroot */ 158*7421Sroot #define IPCPRI PZERO 159*7421Sroot 160*7421Sroot /* 161*7421Sroot * Tracing variables. 162*7421Sroot * Used to pass trace command from 163*7421Sroot * parent to child being traced. 164*7421Sroot * This data base cannot be 165*7421Sroot * shared and is locked 166*7421Sroot * per user. 167*7421Sroot */ 168*7421Sroot struct { 169*7421Sroot int ip_lock; 170*7421Sroot int ip_req; 171*7421Sroot int *ip_addr; 172*7421Sroot int ip_data; 173*7421Sroot } ipc; 174*7421Sroot 175*7421Sroot /* 176*7421Sroot * Send the specified signal to 177*7421Sroot * all processes with 'pgrp' as 178*7421Sroot * process group. 179*7421Sroot * Called by tty.c for quits and 180*7421Sroot * interrupts. 181*7421Sroot */ 182*7421Sroot gsignal(pgrp, sig) 183*7421Sroot register int pgrp; 184*7421Sroot { 185*7421Sroot register struct proc *p; 186*7421Sroot 187*7421Sroot if (pgrp == 0) 188*7421Sroot return; 189*7421Sroot for(p = proc; p < procNPROC; p++) 190*7421Sroot if (p->p_pgrp == pgrp) 191*7421Sroot psignal(p, sig); 192*7421Sroot } 193*7421Sroot 194*7421Sroot /* 195*7421Sroot * Send the specified signal to 196*7421Sroot * the specified process. 197*7421Sroot */ 198*7421Sroot psignal(p, sig) 199*7421Sroot register struct proc *p; 200*7421Sroot register int sig; 201*7421Sroot { 202*7421Sroot register int s; 203*7421Sroot register int (*action)(); 204*7421Sroot long sigmask; 205*7421Sroot 206*7421Sroot if ((unsigned)sig >= NSIG) 207*7421Sroot return; 208*7421Sroot sigmask = (1L << (sig-1)); 209*7421Sroot 210*7421Sroot /* 211*7421Sroot * If proc is traced, always give parent a chance. 212*7421Sroot * Otherwise get the signal action from the bits in the proc table. 213*7421Sroot */ 214*7421Sroot if (p->p_flag & STRC) 215*7421Sroot action = SIG_DFL; 216*7421Sroot else { 217*7421Sroot s = (p->p_siga1&sigmask) != 0; 218*7421Sroot s <<= 1; 219*7421Sroot s |= (p->p_siga0&sigmask) != 0; 220*7421Sroot action = (int(*)())s; 221*7421Sroot /* 222*7421Sroot * If the signal is ignored, we forget about it immediately. 223*7421Sroot */ 224*7421Sroot if (action == SIG_IGN) 225*7421Sroot return; 226*7421Sroot } 227*7421Sroot #define mask(sig) (1<<(sig-1)) 228*7421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 229*7421Sroot if (sig) { 230*7421Sroot p->p_sig |= sigmask; 231*7421Sroot switch (sig) { 232*7421Sroot 233*7421Sroot case SIGTERM: 234*7421Sroot if ((p->p_flag&STRC) != 0 || action != SIG_DFL) 235*7421Sroot break; 236*7421Sroot /* fall into ... */ 237*7421Sroot 238*7421Sroot case SIGKILL: 239*7421Sroot if (p->p_nice > NZERO) 240*7421Sroot p->p_nice = NZERO; 241*7421Sroot break; 242*7421Sroot 243*7421Sroot case SIGCONT: 244*7421Sroot p->p_sig &= ~stops; 245*7421Sroot break; 246*7421Sroot 247*7421Sroot case SIGSTOP: 248*7421Sroot case SIGTSTP: 249*7421Sroot case SIGTTIN: 250*7421Sroot case SIGTTOU: 251*7421Sroot p->p_sig &= ~mask(SIGCONT); 252*7421Sroot break; 253*7421Sroot } 254*7421Sroot } 255*7421Sroot #undef mask 256*7421Sroot #undef stops 257*7421Sroot /* 258*7421Sroot * Defer further processing for signals which are held. 259*7421Sroot */ 260*7421Sroot if (action == SIG_HOLD) 261*7421Sroot return; 262*7421Sroot s = spl6(); 263*7421Sroot switch (p->p_stat) { 264*7421Sroot 265*7421Sroot case SSLEEP: 266*7421Sroot /* 267*7421Sroot * If process is sleeping at negative priority 268*7421Sroot * we can't interrupt the sleep... the signal will 269*7421Sroot * be noticed when the process returns through 270*7421Sroot * trap() or syscall(). 271*7421Sroot */ 272*7421Sroot if (p->p_pri <= PZERO) 273*7421Sroot goto out; 274*7421Sroot /* 275*7421Sroot * Process is sleeping and traced... make it runnable 276*7421Sroot * so it can discover the signal in issig() and stop 277*7421Sroot * for the parent. 278*7421Sroot */ 279*7421Sroot if (p->p_flag&STRC) 280*7421Sroot goto run; 281*7421Sroot switch (sig) { 282*7421Sroot 283*7421Sroot case SIGSTOP: 284*7421Sroot case SIGTSTP: 285*7421Sroot case SIGTTIN: 286*7421Sroot case SIGTTOU: 287*7421Sroot /* 288*7421Sroot * These are the signals which by default 289*7421Sroot * stop a process. 290*7421Sroot */ 291*7421Sroot if (action != SIG_DFL) 292*7421Sroot goto run; 293*7421Sroot /* 294*7421Sroot * Don't clog system with children of init 295*7421Sroot * stopped from the keyboard. 296*7421Sroot */ 297*7421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 298*7421Sroot psignal(p, SIGKILL); 299*7421Sroot p->p_sig &= ~sigmask; 300*7421Sroot splx(s); 301*7421Sroot return; 302*7421Sroot } 303*7421Sroot /* 304*7421Sroot * If a child in vfork(), stopping could 305*7421Sroot * cause deadlock. 306*7421Sroot */ 307*7421Sroot if (p->p_flag&SVFORK) 308*7421Sroot goto out; 309*7421Sroot p->p_sig &= ~sigmask; 310*7421Sroot p->p_cursig = sig; 311*7421Sroot stop(p); 312*7421Sroot goto out; 313*7421Sroot 314*7421Sroot case SIGIO: 315*7421Sroot case SIGURG: 316*7421Sroot case SIGCHLD: 317*7421Sroot /* 318*7421Sroot * These signals are special in that they 319*7421Sroot * don't get propogated... if the process 320*7421Sroot * isn't interested, forget it. 321*7421Sroot */ 322*7421Sroot if (action != SIG_DFL) 323*7421Sroot goto run; 324*7421Sroot p->p_sig &= ~sigmask; /* take it away */ 325*7421Sroot goto out; 326*7421Sroot 327*7421Sroot default: 328*7421Sroot /* 329*7421Sroot * All other signals cause the process to run 330*7421Sroot */ 331*7421Sroot goto run; 332*7421Sroot } 333*7421Sroot /*NOTREACHED*/ 334*7421Sroot 335*7421Sroot case SSTOP: 336*7421Sroot /* 337*7421Sroot * If traced process is already stopped, 338*7421Sroot * then no further action is necessary. 339*7421Sroot */ 340*7421Sroot if (p->p_flag&STRC) 341*7421Sroot goto out; 342*7421Sroot switch (sig) { 343*7421Sroot 344*7421Sroot case SIGKILL: 345*7421Sroot /* 346*7421Sroot * Kill signal always sets processes running. 347*7421Sroot */ 348*7421Sroot goto run; 349*7421Sroot 350*7421Sroot case SIGCONT: 351*7421Sroot /* 352*7421Sroot * If the process catches SIGCONT, let it handle 353*7421Sroot * the signal itself. If it isn't waiting on 354*7421Sroot * an event, then it goes back to run state. 355*7421Sroot * Otherwise, process goes back to sleep state. 356*7421Sroot */ 357*7421Sroot if (action != SIG_DFL || p->p_wchan == 0) 358*7421Sroot goto run; 359*7421Sroot p->p_stat = SSLEEP; 360*7421Sroot goto out; 361*7421Sroot 362*7421Sroot case SIGSTOP: 363*7421Sroot case SIGTSTP: 364*7421Sroot case SIGTTIN: 365*7421Sroot case SIGTTOU: 366*7421Sroot /* 367*7421Sroot * Already stopped, don't need to stop again. 368*7421Sroot * (If we did the shell could get confused.) 369*7421Sroot */ 370*7421Sroot p->p_sig &= ~sigmask; /* take it away */ 371*7421Sroot goto out; 372*7421Sroot 373*7421Sroot default: 374*7421Sroot /* 375*7421Sroot * If process is sleeping interruptibly, then 376*7421Sroot * unstick it so that when it is continued 377*7421Sroot * it can look at the signal. 378*7421Sroot * But don't setrun the process as its not to 379*7421Sroot * be unstopped by the signal alone. 380*7421Sroot */ 381*7421Sroot if (p->p_wchan && p->p_pri > PZERO) 382*7421Sroot unsleep(p); 383*7421Sroot goto out; 384*7421Sroot } 385*7421Sroot /*NOTREACHED*/ 386*7421Sroot 387*7421Sroot default: 388*7421Sroot /* 389*7421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 390*7421Sroot * other than kicking ourselves if we are running. 391*7421Sroot * It will either never be noticed, or noticed very soon. 392*7421Sroot */ 393*7421Sroot if (p == u.u_procp && !noproc) 394*7421Sroot aston(); 395*7421Sroot goto out; 396*7421Sroot } 397*7421Sroot /*NOTREACHED*/ 398*7421Sroot run: 399*7421Sroot /* 400*7421Sroot * Raise priority to at least PUSER. 401*7421Sroot */ 402*7421Sroot if (p->p_pri > PUSER) 403*7421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 404*7421Sroot (p->p_flag & SLOAD)) { 405*7421Sroot remrq(p); 406*7421Sroot p->p_pri = PUSER; 407*7421Sroot setrq(p); 408*7421Sroot } else 409*7421Sroot p->p_pri = PUSER; 410*7421Sroot setrun(p); 411*7421Sroot out: 412*7421Sroot splx(s); 413*7421Sroot } 414*7421Sroot 415*7421Sroot /* 416*7421Sroot * Returns true if the current 417*7421Sroot * process has a signal to process. 418*7421Sroot * The signal to process is put in p_cursig. 419*7421Sroot * This is asked at least once each time a process enters the 420*7421Sroot * system (though this can usually be done without actually 421*7421Sroot * calling issig by checking the pending signal masks.) 422*7421Sroot * A signal does not do anything 423*7421Sroot * directly to a process; it sets 424*7421Sroot * a flag that asks the process to 425*7421Sroot * do something to itself. 426*7421Sroot */ 427*7421Sroot issig() 428*7421Sroot { 429*7421Sroot register struct proc *p; 430*7421Sroot register int sig; 431*7421Sroot long sigbits; 432*7421Sroot long sigmask; 433*7421Sroot 434*7421Sroot p = u.u_procp; 435*7421Sroot for (;;) { 436*7421Sroot sigbits = p->p_sig; 437*7421Sroot if ((p->p_flag&STRC) == 0) 438*7421Sroot sigbits &= ~p->p_ignsig; 439*7421Sroot if (p->p_flag&SVFORK) 440*7421Sroot #define bit(a) (1<<(a-1)) 441*7421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 442*7421Sroot if (sigbits == 0) 443*7421Sroot break; 444*7421Sroot sig = ffs((int)sigbits); 445*7421Sroot sigmask = 1L << (sig-1); 446*7421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 447*7421Sroot p->p_cursig = sig; 448*7421Sroot if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) { 449*7421Sroot /* 450*7421Sroot * If traced, always stop, and stay 451*7421Sroot * stopped until released by the parent. 452*7421Sroot */ 453*7421Sroot do { 454*7421Sroot stop(p); 455*7421Sroot swtch(); 456*7421Sroot } while (!procxmt() && p->p_flag&STRC); 457*7421Sroot 458*7421Sroot /* 459*7421Sroot * If the traced bit got turned off, 460*7421Sroot * then put the signal taken above back into p_sig 461*7421Sroot * and go back up to the top to rescan signals. 462*7421Sroot * This ensures that siga0 and u_signal are consistent. 463*7421Sroot */ 464*7421Sroot if ((p->p_flag&STRC) == 0) { 465*7421Sroot p->p_sig |= sigmask; 466*7421Sroot continue; 467*7421Sroot } 468*7421Sroot 469*7421Sroot /* 470*7421Sroot * If parent wants us to take the signal, 471*7421Sroot * then it will leave it in p->p_cursig; 472*7421Sroot * otherwise we just look for signals again. 473*7421Sroot */ 474*7421Sroot sig = p->p_cursig; 475*7421Sroot if (sig == 0) 476*7421Sroot continue; 477*7421Sroot } 478*7421Sroot switch (u.u_signal[sig]) { 479*7421Sroot 480*7421Sroot case SIG_DFL: 481*7421Sroot /* 482*7421Sroot * Don't take default actions on system processes. 483*7421Sroot */ 484*7421Sroot if (p->p_ppid == 0) 485*7421Sroot break; 486*7421Sroot switch (sig) { 487*7421Sroot 488*7421Sroot case SIGTSTP: 489*7421Sroot case SIGTTIN: 490*7421Sroot case SIGTTOU: 491*7421Sroot /* 492*7421Sroot * Children of init aren't allowed to stop 493*7421Sroot * on signals from the keyboard. 494*7421Sroot */ 495*7421Sroot if (p->p_pptr == &proc[1]) { 496*7421Sroot psignal(p, SIGKILL); 497*7421Sroot continue; 498*7421Sroot } 499*7421Sroot /* fall into ... */ 500*7421Sroot 501*7421Sroot case SIGSTOP: 502*7421Sroot if (p->p_flag&STRC) 503*7421Sroot continue; 504*7421Sroot stop(p); 505*7421Sroot swtch(); 506*7421Sroot continue; 507*7421Sroot 508*7421Sroot case SIGCONT: 509*7421Sroot case SIGCHLD: 510*7421Sroot /* 511*7421Sroot * These signals are normally not 512*7421Sroot * sent if the action is the default. 513*7421Sroot */ 514*7421Sroot continue; /* == ignore */ 515*7421Sroot 516*7421Sroot default: 517*7421Sroot goto send; 518*7421Sroot } 519*7421Sroot /*NOTREACHED*/ 520*7421Sroot 521*7421Sroot case SIG_HOLD: 522*7421Sroot case SIG_IGN: 523*7421Sroot /* 524*7421Sroot * Masking above should prevent us 525*7421Sroot * ever trying to take action on a held 526*7421Sroot * or ignored signal, unless process is traced. 527*7421Sroot */ 528*7421Sroot if ((p->p_flag&STRC) == 0) 529*7421Sroot printf("issig\n"); 530*7421Sroot continue; 531*7421Sroot 532*7421Sroot default: 533*7421Sroot /* 534*7421Sroot * This signal has an action, let 535*7421Sroot * psig process it. 536*7421Sroot */ 537*7421Sroot goto send; 538*7421Sroot } 539*7421Sroot /*NOTREACHED*/ 540*7421Sroot } 541*7421Sroot /* 542*7421Sroot * Didn't find a signal to send. 543*7421Sroot */ 544*7421Sroot p->p_cursig = 0; 545*7421Sroot return (0); 546*7421Sroot 547*7421Sroot send: 548*7421Sroot /* 549*7421Sroot * Let psig process the signal. 550*7421Sroot */ 551*7421Sroot return (sig); 552*7421Sroot } 553*7421Sroot 554*7421Sroot #ifndef vax 555*7421Sroot ffs(mask) 556*7421Sroot register long mask; 557*7421Sroot { 558*7421Sroot register int i; 559*7421Sroot 560*7421Sroot for(i=1; i<NSIG; i++) { 561*7421Sroot if (mask & 1) 562*7421Sroot return (i); 563*7421Sroot mask >>= 1; 564*7421Sroot } 565*7421Sroot return (0); 566*7421Sroot } 567*7421Sroot #endif 568*7421Sroot 569*7421Sroot /* 570*7421Sroot * Put the argument process into the stopped 571*7421Sroot * state and notify the parent via wakeup and/or signal. 572*7421Sroot */ 573*7421Sroot stop(p) 574*7421Sroot register struct proc *p; 575*7421Sroot { 576*7421Sroot 577*7421Sroot p->p_stat = SSTOP; 578*7421Sroot p->p_flag &= ~SWTED; 579*7421Sroot wakeup((caddr_t)p->p_pptr); 580*7421Sroot /* 581*7421Sroot * Avoid sending signal to parent if process is traced 582*7421Sroot */ 583*7421Sroot if (p->p_flag&STRC) 584*7421Sroot return; 585*7421Sroot psignal(p->p_pptr, SIGCHLD); 586*7421Sroot } 587*7421Sroot 588*7421Sroot /* 589*7421Sroot * Perform the action specified by 590*7421Sroot * the current signal. 591*7421Sroot * The usual sequence is: 592*7421Sroot * if (issig()) 593*7421Sroot * psig(); 594*7421Sroot * The signal bit has already been cleared by issig, 595*7421Sroot * and the current signal number stored in p->p_cursig. 596*7421Sroot */ 597*7421Sroot psig() 598*7421Sroot { 599*7421Sroot register struct proc *rp = u.u_procp; 600*7421Sroot register int n = rp->p_cursig; 601*7421Sroot long sigmask = 1L << (n-1); 602*7421Sroot register int (*action)(); 603*7421Sroot 604*7421Sroot if (rp->p_cursig == 0) 605*7421Sroot panic("psig"); 606*7421Sroot action = u.u_signal[n]; 607*7421Sroot if (action != SIG_DFL) { 608*7421Sroot if (action == SIG_IGN || action == SIG_HOLD) 609*7421Sroot panic("psig action"); 610*7421Sroot u.u_error = 0; 611*7421Sroot if (n != SIGILL && n != SIGTRAP) 612*7421Sroot u.u_signal[n] = 0; 613*7421Sroot /* 614*7421Sroot * If this catch value indicates automatic holding of 615*7421Sroot * subsequent signals, set the hold value. 616*7421Sroot */ 617*7421Sroot if (SIGISDEFER(action)) { 618*7421Sroot (void) spl6(); 619*7421Sroot if ((int)SIG_HOLD & 1) 620*7421Sroot rp->p_siga0 |= sigmask; 621*7421Sroot else 622*7421Sroot rp->p_siga0 &= ~sigmask; 623*7421Sroot if ((int)SIG_HOLD & 2) 624*7421Sroot rp->p_siga1 |= sigmask; 625*7421Sroot else 626*7421Sroot rp->p_siga1 &= ~sigmask; 627*7421Sroot u.u_signal[n] = SIG_HOLD; 628*7421Sroot (void) spl0(); 629*7421Sroot action = SIGUNDEFER(action); 630*7421Sroot } 631*7421Sroot sendsig(action, n); 632*7421Sroot rp->p_cursig = 0; 633*7421Sroot return; 634*7421Sroot } 635*7421Sroot u.u_acflag |= AXSIG; 636*7421Sroot switch (n) { 637*7421Sroot 638*7421Sroot case SIGILL: 639*7421Sroot case SIGIOT: 640*7421Sroot case SIGBUS: 641*7421Sroot case SIGQUIT: 642*7421Sroot case SIGTRAP: 643*7421Sroot case SIGEMT: 644*7421Sroot case SIGFPE: 645*7421Sroot case SIGSEGV: 646*7421Sroot case SIGSYS: 647*7421Sroot u.u_arg[0] = n; 648*7421Sroot if (core()) 649*7421Sroot n += 0200; 650*7421Sroot } 651*7421Sroot exit(n); 652*7421Sroot } 653*7421Sroot 654*7421Sroot #ifdef unneeded 655*7421Sroot int corestop = 0; 656*7421Sroot #endif 657*7421Sroot /* 658*7421Sroot * Create a core image on the file "core" 659*7421Sroot * If you are looking for protection glitches, 660*7421Sroot * there are probably a wealth of them here 661*7421Sroot * when this occurs to a suid command. 662*7421Sroot * 663*7421Sroot * It writes UPAGES block of the 664*7421Sroot * user.h area followed by the entire 665*7421Sroot * data+stack segments. 666*7421Sroot */ 667*7421Sroot core() 668*7421Sroot { 669*7421Sroot register struct inode *ip; 670*7421Sroot extern schar(); 671*7421Sroot 672*7421Sroot #ifdef unneeded 673*7421Sroot if (corestop) { 674*7421Sroot int i; 675*7421Sroot for (i = 0; i < 10; i++) 676*7421Sroot if (u.u_comm[i]) 677*7421Sroot putchar(u.u_comm[i], 0); 678*7421Sroot printf(", uid %d\n", u.u_uid); 679*7421Sroot if (corestop&2) 680*7421Sroot asm("halt"); 681*7421Sroot } 682*7421Sroot #endif 683*7421Sroot if (u.u_uid != u.u_ruid) 684*7421Sroot return; 685*7421Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= u.u_limit[LIM_CORE]) 686*7421Sroot return (0); 687*7421Sroot u.u_error = 0; 688*7421Sroot u.u_dirp = "core"; 689*7421Sroot ip = namei(schar, 1, 1); 690*7421Sroot if (ip == NULL) { 691*7421Sroot if (u.u_error) 692*7421Sroot return (0); 693*7421Sroot ip = maknode(0666); 694*7421Sroot if (ip==NULL) 695*7421Sroot return (0); 696*7421Sroot } 697*7421Sroot if (!access(ip, IWRITE) && 698*7421Sroot (ip->i_mode&IFMT) == IFREG && 699*7421Sroot ip->i_nlink == 1) { 700*7421Sroot itrunc(ip); 701*7421Sroot u.u_acflag |= ACORE; 702*7421Sroot u.u_offset = 0; 703*7421Sroot u.u_base = (caddr_t)&u; 704*7421Sroot u.u_count = ctob(UPAGES); 705*7421Sroot u.u_segflg = 1; 706*7421Sroot writei(ip); 707*7421Sroot u.u_base = (char *)ctob(u.u_tsize); 708*7421Sroot u.u_count = ctob(u.u_dsize); 709*7421Sroot u.u_segflg = 0; 710*7421Sroot writei(ip); 711*7421Sroot u.u_base = (char *)(USRSTACK - ctob(u.u_ssize)); 712*7421Sroot u.u_count = ctob(u.u_ssize); 713*7421Sroot writei(ip); 714*7421Sroot } else 715*7421Sroot u.u_error = EFAULT; 716*7421Sroot iput(ip); 717*7421Sroot return (u.u_error==0); 718*7421Sroot } 719*7421Sroot 720*7421Sroot /* 721*7421Sroot * grow the stack to include the SP 722*7421Sroot * true return if successful. 723*7421Sroot */ 724*7421Sroot grow(sp) 725*7421Sroot unsigned sp; 726*7421Sroot { 727*7421Sroot register si; 728*7421Sroot 729*7421Sroot if (sp >= USRSTACK-ctob(u.u_ssize)) 730*7421Sroot return (0); 731*7421Sroot si = clrnd(btoc((USRSTACK-sp)) - u.u_ssize + SINCR); 732*7421Sroot if (ctob(u.u_ssize+si) > u.u_limit[LIM_STACK]) 733*7421Sroot return (0); 734*7421Sroot if (chksize(u.u_tsize, u.u_dsize, u.u_ssize+si)) 735*7421Sroot return (0); 736*7421Sroot if (swpexpand(u.u_dsize, u.u_ssize+si, &u.u_dmap, &u.u_smap)==0) 737*7421Sroot return (0); 738*7421Sroot 739*7421Sroot expand(si, P1BR); 740*7421Sroot return (1); 741*7421Sroot } 742*7421Sroot 743*7421Sroot /* 744*7421Sroot * sys-trace system call. 745*7421Sroot */ 746*7421Sroot ptrace() 747*7421Sroot { 748*7421Sroot register struct proc *p; 749*7421Sroot register struct a { 750*7421Sroot int req; 751*7421Sroot int pid; 752*7421Sroot int *addr; 753*7421Sroot int data; 754*7421Sroot } *uap; 755*7421Sroot 756*7421Sroot uap = (struct a *)u.u_ap; 757*7421Sroot if (uap->req <= 0) { 758*7421Sroot u.u_procp->p_flag |= STRC; 759*7421Sroot return; 760*7421Sroot } 761*7421Sroot p = pfind(uap->pid); 762*7421Sroot if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) { 763*7421Sroot u.u_error = ESRCH; 764*7421Sroot return; 765*7421Sroot } 766*7421Sroot while (ipc.ip_lock) 767*7421Sroot sleep((caddr_t)&ipc, IPCPRI); 768*7421Sroot ipc.ip_lock = p->p_pid; 769*7421Sroot ipc.ip_data = uap->data; 770*7421Sroot ipc.ip_addr = uap->addr; 771*7421Sroot ipc.ip_req = uap->req; 772*7421Sroot p->p_flag &= ~SWTED; 773*7421Sroot while (ipc.ip_req > 0) { 774*7421Sroot if (p->p_stat==SSTOP) 775*7421Sroot setrun(p); 776*7421Sroot sleep((caddr_t)&ipc, IPCPRI); 777*7421Sroot } 778*7421Sroot u.u_r.r_val1 = ipc.ip_data; 779*7421Sroot if (ipc.ip_req < 0) 780*7421Sroot u.u_error = EIO; 781*7421Sroot ipc.ip_lock = 0; 782*7421Sroot wakeup((caddr_t)&ipc); 783*7421Sroot } 784*7421Sroot 785*7421Sroot int ipcreg[] = {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; 786*7421Sroot /* 787*7421Sroot * Code that the child process 788*7421Sroot * executes to implement the command 789*7421Sroot * of the parent process in tracing. 790*7421Sroot */ 791*7421Sroot procxmt() 792*7421Sroot { 793*7421Sroot register int i; 794*7421Sroot register *p; 795*7421Sroot register struct text *xp; 796*7421Sroot 797*7421Sroot if (ipc.ip_lock != u.u_procp->p_pid) 798*7421Sroot return (0); 799*7421Sroot u.u_procp->p_slptime = 0; 800*7421Sroot i = ipc.ip_req; 801*7421Sroot ipc.ip_req = 0; 802*7421Sroot switch (i) { 803*7421Sroot 804*7421Sroot /* read user I */ 805*7421Sroot case 1: 806*7421Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 807*7421Sroot goto error; 808*7421Sroot ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); 809*7421Sroot break; 810*7421Sroot 811*7421Sroot /* read user D */ 812*7421Sroot case 2: 813*7421Sroot if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) 814*7421Sroot goto error; 815*7421Sroot ipc.ip_data = fuword((caddr_t)ipc.ip_addr); 816*7421Sroot break; 817*7421Sroot 818*7421Sroot /* read u */ 819*7421Sroot case 3: 820*7421Sroot i = (int)ipc.ip_addr; 821*7421Sroot if (i<0 || i >= ctob(UPAGES)) 822*7421Sroot goto error; 823*7421Sroot ipc.ip_data = ((physadr)&u)->r[i>>2]; 824*7421Sroot break; 825*7421Sroot 826*7421Sroot /* write user I */ 827*7421Sroot /* Must set up to allow writing */ 828*7421Sroot case 4: 829*7421Sroot /* 830*7421Sroot * If text, must assure exclusive use 831*7421Sroot */ 832*7421Sroot if (xp = u.u_procp->p_textp) { 833*7421Sroot if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) 834*7421Sroot goto error; 835*7421Sroot xp->x_iptr->i_flag &= ~ITEXT; 836*7421Sroot } 837*7421Sroot i = -1; 838*7421Sroot if (chgprot((caddr_t)ipc.ip_addr, RW) && 839*7421Sroot chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) 840*7421Sroot i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); 841*7421Sroot (void) chgprot((caddr_t)ipc.ip_addr, RO); 842*7421Sroot (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); 843*7421Sroot if (i < 0) 844*7421Sroot goto error; 845*7421Sroot if (xp) 846*7421Sroot xp->x_flag |= XWRIT; 847*7421Sroot break; 848*7421Sroot 849*7421Sroot /* write user D */ 850*7421Sroot case 5: 851*7421Sroot if (suword((caddr_t)ipc.ip_addr, 0) < 0) 852*7421Sroot goto error; 853*7421Sroot (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); 854*7421Sroot break; 855*7421Sroot 856*7421Sroot /* write u */ 857*7421Sroot case 6: 858*7421Sroot i = (int)ipc.ip_addr; 859*7421Sroot p = (int *)&((physadr)&u)->r[i>>2]; 860*7421Sroot for (i=0; i<16; i++) 861*7421Sroot if (p == &u.u_ar0[ipcreg[i]]) 862*7421Sroot goto ok; 863*7421Sroot if (p == &u.u_ar0[PS]) { 864*7421Sroot ipc.ip_data |= PSL_CURMOD|PSL_PRVMOD; 865*7421Sroot ipc.ip_data &= ~PSL_USERCLR; 866*7421Sroot goto ok; 867*7421Sroot } 868*7421Sroot goto error; 869*7421Sroot 870*7421Sroot ok: 871*7421Sroot *p = ipc.ip_data; 872*7421Sroot break; 873*7421Sroot 874*7421Sroot /* set signal and continue */ 875*7421Sroot /* one version causes a trace-trap */ 876*7421Sroot case 9: 877*7421Sroot case 7: 878*7421Sroot if ((int)ipc.ip_addr != 1) 879*7421Sroot u.u_ar0[PC] = (int)ipc.ip_addr; 880*7421Sroot if ((unsigned)ipc.ip_data > NSIG) 881*7421Sroot goto error; 882*7421Sroot u.u_procp->p_cursig = ipc.ip_data; /* see issig */ 883*7421Sroot if (i == 9) 884*7421Sroot u.u_ar0[PS] |= PSL_T; 885*7421Sroot wakeup((caddr_t)&ipc); 886*7421Sroot return (1); 887*7421Sroot 888*7421Sroot /* force exit */ 889*7421Sroot case 8: 890*7421Sroot wakeup((caddr_t)&ipc); 891*7421Sroot exit(u.u_procp->p_cursig); 892*7421Sroot 893*7421Sroot default: 894*7421Sroot error: 895*7421Sroot ipc.ip_req = -1; 896*7421Sroot } 897*7421Sroot wakeup((caddr_t)&ipc); 898*7421Sroot return (0); 899*7421Sroot } 900