1: /*
   2:  *	SCCS id	@(#)signojcl.c	2.1 (Berkeley)	9/4/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/dir.h>
   8: #include <sys/user.h>
   9: #include <sys/proc.h>
  10: #include <sys/inode.h>
  11: #include <sys/reg.h>
  12: #include <sys/text.h>
  13: #include <sys/seg.h>
  14: #ifdef UCB_METER
  15: #include <sys/vm.h>
  16: #endif
  17: 
  18: 
  19: /*
  20:  * Priority for tracing
  21:  */
  22: #define IPCPRI  PZERO
  23: 
  24: /*
  25:  * Tracing variables.
  26:  * Used to pass trace command from
  27:  * parent to child being traced.
  28:  * This data base cannot be
  29:  * shared and is locked
  30:  * per user.
  31:  */
  32: struct
  33: {
  34:     int ip_lock;
  35:     int ip_req;
  36:     int *ip_addr;
  37:     int ip_data;
  38: } ipc;
  39: 
  40: /*
  41:  * Send the specified signal to
  42:  * all processes with 'pgrp' as
  43:  * process group.
  44:  * Called by tty*.c for quits and
  45:  * interrupts.
  46:  */
  47: gsignal(pgrp, sig)
  48: register pgrp;
  49: {
  50:     register struct proc *p;
  51: 
  52:     if(pgrp == 0)
  53:         return;
  54:     for(p = &proc[0]; p <= maxproc; p++)
  55:         if(p->p_pgrp == pgrp)
  56:             psignal(p, sig);
  57: }
  58: 
  59: /*
  60:  * Send the specified signal to
  61:  * the specified process.
  62:  */
  63: psignal(p, sig)
  64: register struct proc *p;
  65: register sig;
  66: {
  67: 
  68:     if((unsigned)sig >= NSIG)
  69:         return;
  70:     if(sig)
  71:         p->p_sig |= 1<<(sig-1);
  72:     if(p->p_pri > PUSER)
  73:         p->p_pri = PUSER;
  74:     if(p->p_stat == SSLEEP && p->p_pri > PZERO)
  75:         setrun(p);
  76: }
  77: 
  78: /*
  79:  * Returns true if the current
  80:  * process has a signal to process.
  81:  * This is asked at least once
  82:  * each time a process enters the
  83:  * system.
  84:  * A signal does not do anything
  85:  * directly to a process; it sets
  86:  * a flag that asks the process to
  87:  * do something to itself.
  88:  */
  89: issig()
  90: {
  91:     register n;
  92:     register struct proc *p;
  93: 
  94:     p = u.u_procp;
  95:     while(p->p_sig) {
  96:         n = fsig(p);
  97:         if(((int)u.u_signal[n]&1) == 0 || (p->p_flag&STRC))
  98:             return(n);
  99:         p->p_sig &= ~(1<<(n-1));
 100:     }
 101:     return(0);
 102: }
 103: 
 104: /*
 105:  * Enter the tracing STOP state.
 106:  * In this state, the parent is
 107:  * informed and the process is able to
 108:  * receive commands from the parent.
 109:  */
 110: stop()
 111: {
 112:     register struct proc *pp, *cp;
 113: 
 114: loop:
 115:     cp = u.u_procp;
 116:     if(cp->p_ppid != 1)
 117:     for (pp = &proc[0]; pp <= maxproc; pp++)
 118:         if (pp->p_pid == cp->p_ppid) {
 119:             wakeup((caddr_t)pp);
 120:             cp->p_stat = SSTOP;
 121:             swtch();
 122:             if ((cp->p_flag&STRC)==0 || procxmt())
 123:                 return;
 124:             goto loop;
 125:         }
 126:     exit(fsig(u.u_procp));
 127: }
 128: 
 129: /*
 130:  * Perform the action specified by
 131:  * the current signal.
 132:  * The usual sequence is:
 133:  *	if(issig())
 134:  *		psig();
 135:  */
 136: psig()
 137: {
 138:     register n, p;
 139:     register struct proc *rp;
 140: 
 141:     rp = u.u_procp;
 142: #ifndef NONFP
 143:     if (u.u_fpsaved==0) {
 144:         savfp(&u.u_fps);
 145:         u.u_fpsaved = 1;
 146:     }
 147:     if (rp->p_flag&STRC)
 148:         stop();
 149: #else
 150:     /* allow normal action on SIGILL even if traced */
 151:     n = fsig(rp);
 152:     if ((rp->p_flag&STRC) && (n!=SIGILL || u.u_signal[SIGILL]==0))
 153:         stop();
 154: #endif
 155:     while(n = fsig(rp)) {
 156:         rp->p_sig &= ~(1<<(n-1));
 157:         if((p=u.u_signal[n]) != 0) {
 158:             u.u_error = 0;
 159:             if (u.u_signal[n] == 1)
 160:                 continue;
 161:             if(n != SIGILL && n != SIGTRAP)
 162:                 u.u_signal[n] = 0;
 163:             sendsig((caddr_t)p);
 164:         } else {
 165:             switch(n) {
 166: 
 167:             case SIGQUIT:
 168:             case SIGILL:
 169:             case SIGTRAP:
 170:             case SIGIOT:
 171:             case SIGEMT:
 172:             case SIGFPE:
 173:             case SIGBUS:
 174:             case SIGSEGV:
 175:             case SIGSYS:
 176:                 if(core())
 177:                     n += 0200;
 178:             }
 179:             exit(n);
 180:         }
 181:     }
 182: }
 183: 
 184: /*
 185:  * This table defines the order in which signals
 186:  * will be reflected to the user process.  Signals
 187:  * later in the list will be stacked after (processed
 188:  * before) signals earlier in the list.  The value
 189:  * contained in the list is the signal number.
 190:  */
 191: 
 192: char    siglist[] = {
 193:     SIGKILL,    /* kill				*/
 194:     SIGTERM,    /* terminate			*/
 195:     SIGILL,     /* illegal instruction		*/
 196:     SIGTRAP,    /* trace trap			*/
 197:     SIGIOT,     /* iot				*/
 198:     SIGEMT,     /* emt				*/
 199:     SIGBUS,     /* bus error			*/
 200:     SIGSEGV,    /* segmentation error		*/
 201:     SIGSYS,     /* invalid system call (unused)	*/
 202:     SIGQUIT,    /* quit				*/
 203:     SIGINT,     /* interrupt			*/
 204:     SIGHUP,     /* hangup			*/
 205:     SIGPIPE,    /* broken pipe			*/
 206:     SIGALRM,    /* alarm clock			*/
 207:     SIGFPE,     /* floating exception		*/
 208:     16,     /* unassigned			*/
 209:      0,     /* end of list			*/
 210: };
 211: 
 212: /*
 213:  * find the highest-priority signal in
 214:  * bit-position representation in p_sig.
 215:  */
 216: fsig(p)
 217: struct proc *p;
 218: {
 219:     register char *cp;
 220:     register psig;
 221: 
 222:     psig = p->p_sig;
 223:     for(cp=siglist; *cp; cp++)
 224:         if(psig & (1 << (*cp-1)))
 225:             return(*cp);
 226:     return(0);
 227: }
 228: 
 229: /*
 230:  * Create a core image on the file "core"
 231:  * If you are looking for protection glitches,
 232:  * there are probably a wealth of them here
 233:  * when this occurs to a suid command.
 234:  *
 235:  * It writes USIZE block of the
 236:  * user.h area followed by the entire
 237:  * data+stack segments.
 238:  */
 239: core()
 240: {
 241:     register struct inode *ip;
 242:     register unsigned s;
 243:     extern schar();
 244: 
 245:     u.u_error = 0;
 246: 
 247:     /*
 248: 	 * Disallow dump if setuid/setgid.
 249: 	 */
 250:     if (u.u_gid != u.u_rgid || u.u_uid != u.u_ruid)
 251:         return(0);
 252: 
 253:     u.u_dirp = "core";
 254: #ifndef UCB_SYMLINKS
 255:     ip = namei(schar, CREATE);
 256: #else
 257:     ip = namei(schar, CREATE, 1);
 258: #endif
 259:     if(ip == NULL) {
 260:         if(u.u_error)
 261:             return(0);
 262:         ip = maknode(0666);
 263:         if (ip == NULL)
 264:             return(0);
 265:     }
 266:     /*
 267: 	 * allow dump only if permissions allow, "core" is
 268: 	 * regular file and has exactly one link
 269: 	 */
 270:     if (!access(ip, IWRITE) &&
 271:        (ip->i_mode&IFMT) == IFREG &&
 272:        ip->i_nlink == 1) {
 273:         itrunc(ip);
 274:         u.u_offset = 0;
 275:         u.u_base = (caddr_t)&u;
 276:         u.u_count = ctob(USIZE);
 277:         u.u_segflg = 1;
 278:         writei(ip);
 279: #ifdef  VIRUS_VFORK
 280:         s = u.u_dsize;
 281:         estabur((unsigned)0, s, u.u_ssize, 0, RO);
 282:         u.u_base = 0;
 283:         u.u_count = ctob(s);
 284:         u.u_segflg = 0;
 285:         writei(ip);
 286:         s = u.u_ssize;
 287:         u.u_base = -(ctob(s));
 288:         u.u_count = ctob(s);
 289:         writei(ip);
 290: #else
 291:         s = u.u_procp->p_size - USIZE;
 292:         estabur((unsigned)0, s, (unsigned)0, 0, RO);
 293:         u.u_base = 0;
 294:         u.u_count = ctob(s);
 295:         u.u_segflg = 0;
 296:         writei(ip);
 297: #endif
 298:     }
 299:     iput(ip);
 300:     return(u.u_error==0);
 301: }
 302: 
 303: /*
 304:  * grow the stack to include the SP
 305:  * true return if successful.
 306:  */
 307: 
 308: grow(sp)
 309: unsigned sp;
 310: {
 311:     register si;
 312: #ifndef VIRUS_VFORK
 313:     register i;
 314: #endif
 315:     register struct proc *p;
 316:     register a;
 317: 
 318:     if(sp >= -ctob(u.u_ssize))
 319:         return(0);
 320:     si = (-sp)/ctob(1) - u.u_ssize + SINCR;
 321:     /*
 322: 	 * Round the increment back to a segment boundary if necessary.
 323: 	 */
 324:     if (ctos(si + u.u_ssize) > ctos(((-sp)+ctob(1)-1) / ctob(1)))
 325:         si = stoc(ctos(((-sp)+ctob(1)-1) / ctob(1))) - u.u_ssize;
 326:     if(si <= 0)
 327:         return(0);
 328:     if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep, RO))
 329:         return(0);
 330:     p = u.u_procp;
 331: #ifdef  VIRUS_VFORK
 332:     /*
 333: 	 *  expand will put the stack in the right place;
 334: 	 *  no copy required here.
 335: 	 */
 336:     expand(u.u_ssize+si,S_STACK);
 337:     u.u_ssize += si;
 338:     clear(u.u_procp->p_saddr, si);
 339: 
 340: #else   VIRUS_VFORK
 341:     expand(p->p_size+si);
 342:     a = u.u_procp->p_addr + USIZE + u.u_dsize;
 343:     i = u.u_ssize;
 344:     while (i >= si) {
 345:         i -= si;
 346:         copy(a+i, a+i+si, si);
 347:     }
 348:     copy(a, a+si, i);
 349:     clear(a, si);
 350:     u.u_ssize += si;
 351: #endif	VIRUS_VFORK
 352:     return(1);
 353: }
 354: 
 355: /*
 356:  * sys-trace system call.
 357:  */
 358: ptrace()
 359: {
 360:     register struct proc *p;
 361:     register struct a {
 362:         int data;
 363:         int pid;
 364:         int *addr;
 365:         int req;
 366:     } *uap;
 367: 
 368:     uap = (struct a *)u.u_ap;
 369:     if (uap->req <= 0) {
 370:         u.u_procp->p_flag |= STRC;
 371:         return;
 372:     }
 373:     for (p = proc; p <= maxproc; p++)
 374:         if (p->p_stat == SSTOP && p->p_pid == uap->pid
 375:             && p->p_ppid == u.u_procp->p_pid) {
 376:         while (ipc.ip_lock)
 377:             sleep((caddr_t)&ipc, IPCPRI);
 378:         ipc.ip_lock = p->p_pid;
 379:         ipc.ip_data = uap->data;
 380:         ipc.ip_addr = uap->addr;
 381:         ipc.ip_req = uap->req;
 382:         p->p_flag &= ~SWTED;
 383:         setrun(p);
 384:         while (ipc.ip_req > 0)
 385:             sleep((caddr_t)&ipc, IPCPRI);
 386:         u.u_r.r_val1 = ipc.ip_data;
 387:         if (ipc.ip_req < 0)
 388:             u.u_error = EIO;
 389:         ipc.ip_lock = 0;
 390:         wakeup((caddr_t)&ipc);
 391:         return;
 392:     }
 393: 
 394:     u.u_error = ESRCH;
 395: }
 396: 
 397: /*
 398:  * Code that the child process
 399:  * executes to implement the command
 400:  * of the parent process in tracing.
 401:  */
 402: procxmt()
 403: {
 404:     register int i;
 405:     register *p;
 406:     register struct text *xp;
 407: 
 408:     if (ipc.ip_lock != u.u_procp->p_pid)
 409:         return(0);
 410: #ifdef UCB_METER
 411:     u.u_procp->p_slptime = 0;
 412: #endif
 413:     i = ipc.ip_req;
 414:     ipc.ip_req = 0;
 415:     wakeup((caddr_t)&ipc);
 416:     switch (i) {
 417: 
 418:     /* read user I */
 419:     case 1:
 420: #ifndef NONSEPARATE     /* I and D are the same if nonsep */
 421:         if (fuibyte((caddr_t)ipc.ip_addr) == -1)
 422:             goto error;
 423:         ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
 424:         break;
 425: 
 426: #endif
 427:     /* read user D */
 428:     case 2:
 429:         if (fubyte((caddr_t)ipc.ip_addr) == -1)
 430:             goto error;
 431:         ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
 432:         break;
 433: 
 434:     /* read u */
 435:     case 3:
 436:         i = (int)ipc.ip_addr;
 437:         if (i<0 || i >= ctob(USIZE))
 438:             goto error;
 439:         ipc.ip_data = ((physadr)&u)->r[i>>1];
 440:         break;
 441: 
 442:     /* write user I */
 443:     /* Must set up to allow writing */
 444:     case 4:
 445:         /*
 446: 		 * If text, must assure exclusive use
 447: 		 */
 448:         if (xp = u.u_procp->p_textp) {
 449:             if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
 450:                 goto error;
 451:             xp->x_iptr->i_flag &= ~ITEXT;
 452:         }
 453:         estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RW);
 454:         i = suiword((caddr_t)ipc.ip_addr, 0);
 455:         suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
 456:         estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RO);
 457:         if (i<0)
 458:             goto error;
 459:         if (xp)
 460:             xp->x_flag |= XWRIT;
 461:         break;
 462: 
 463:     /* write user D */
 464:     case 5:
 465:         if (suword((caddr_t)ipc.ip_addr, 0) < 0)
 466:             goto error;
 467:         suword((caddr_t)ipc.ip_addr, ipc.ip_data);
 468:         break;
 469: 
 470:     /* write u */
 471:     case 6:
 472:         i = (int)ipc.ip_addr;
 473:         p = (int *)&((physadr)&u)->r[i>>1];
 474: #ifndef NONFP
 475:         if (p >= (int *)&u.u_fps && p < (int *)&u.u_fps.u_fpregs[6])
 476:             goto ok;
 477: #endif
 478:         for (i=0; i<8; i++)
 479:             if (p == &u.u_ar0[regloc[i]])
 480:                 goto ok;
 481:         if (p == &u.u_ar0[RPS]) {
 482:             ipc.ip_data |= PS_CURMOD | PS_PRVMOD;   /* user space */
 483:             ipc.ip_data &= ~PS_USERCLR;     /* priority 0 */
 484:             goto ok;
 485:         }
 486: #ifdef  MENLO_OVLY
 487:         if ((p == &u.u_ovdata.uo_curov) && ((ipc.ip_data >= 0) &&
 488:             (ipc.ip_data <= NOVL) && u.u_ovdata.uo_ovbase)) {
 489:             *p = ipc.ip_data;
 490:             choverlay(RO);
 491:             break;
 492:         }
 493: #endif
 494:         goto error;
 495: 
 496:     ok:
 497:         *p = ipc.ip_data;
 498:         break;
 499: 
 500:     /* set signal and continue */
 501:     /*  one version causes a trace-trap */
 502:     case 9:
 503:         u.u_ar0[RPS] |= PS_T;
 504:         /* FALL THROUGH TO ... */
 505:     case 7:
 506:         if ((int)ipc.ip_addr != 1)
 507:             u.u_ar0[PC] = (int)ipc.ip_addr;
 508:         u.u_procp->p_sig = 0;
 509:         if (ipc.ip_data)
 510:             psignal(u.u_procp, ipc.ip_data);
 511:         return(1);
 512: 
 513:     /* force exit */
 514:     case 8:
 515:         exit(fsig(u.u_procp));
 516:         /*NOTREACHED*/
 517: 
 518:     default:
 519:     error:
 520:         ipc.ip_req = -1;
 521:     }
 522:     return(0);
 523: }

Defined functions

core defined in line 239; used 1 times
fsig defined in line 216; used 6 times
grow defined in line 308; never used
gsignal defined in line 47; never used
issig defined in line 89; never used
procxmt defined in line 402; used 1 times
psig defined in line 136; used 3 times
psignal defined in line 63; used 2 times
ptrace defined in line 358; never used
stop defined in line 110; used 2 times

Defined variables

siglist defined in line 192; used 1 times

Defined struct's

a defined in line 361; used 2 times
  • in line 368(2)

Defined macros

IPCPRI defined in line 22; used 2 times

Usage of this include

signojcl.c used 1 times
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1250
Valid CSS Valid XHTML 1.0 Strict