1: #
   2: /*
   3:  */
   4: 
   5: #include "../param.h"
   6: #include "../systm.h"
   7: #include "../user.h"
   8: #include "../proc.h"
   9: #include "../inode.h"
  10: #include "../reg.h"
  11: 
  12: /*
  13:  * Priority for tracing
  14:  */
  15: #define IPCPRI  (-1)
  16: 
  17: /*
  18:  * Structure to access an array of integers.
  19:  */
  20: struct
  21: {
  22:     int inta[];
  23: };
  24: 
  25: /*
  26:  * Tracing variables.
  27:  * Used to pass trace command from
  28:  * parent to child being traced.
  29:  * This data base cannot be
  30:  * shared and is locked
  31:  * per user.
  32:  */
  33: struct
  34: {
  35:     int ip_lock;
  36:     int ip_req;
  37:     int ip_addr;
  38:     int ip_data;
  39: } ipc;
  40: 
  41: /*
  42:  * Send the specified signal to
  43:  * all processes with 'tp' as its
  44:  * controlling teletype.
  45:  * Called by tty.c for quits and
  46:  * interrupts.
  47:  */
  48: signal(tp, sig)
  49: {
  50:     register struct proc *p;
  51: 
  52:     for(p = &proc[0]; p < &proc[NPROC]; p++)
  53:         if(p->p_ttyp == tp)
  54:             psignal(p, sig);
  55: }
  56: 
  57: /*
  58:  * Send the specified signal to
  59:  * the specified process.
  60:  */
  61: psignal(p, sig)
  62: int *p;
  63: {
  64:     register *rp;
  65: 
  66:     if(sig >= NSIG)
  67:         return;
  68:     rp = p;
  69:     if(rp->p_sig != SIGKIL)
  70:         rp->p_sig = sig;
  71:     if(rp->p_stat > PUSER)
  72:         rp->p_stat = PUSER;
  73:     if(rp->p_stat == SWAIT)
  74:         setrun(rp);
  75: }
  76: 
  77: /*
  78:  * Returns true if the current
  79:  * process has a signal to process.
  80:  * This is asked at least once
  81:  * each time a process enters the
  82:  * system.
  83:  * A signal does not do anything
  84:  * directly to a process; it sets
  85:  * a flag that asks the process to
  86:  * do something to itself.
  87:  */
  88: issig()
  89: {
  90:     register n;
  91:     register struct proc *p;
  92: 
  93:     p = u.u_procp;
  94:     if(n = p->p_sig) {
  95:         if (p->p_flag&STRC) {
  96:             stop();
  97:             if ((n = p->p_sig) == 0)
  98:                 return(0);
  99:         }
 100:         if((u.u_signal[n]&1) == 0)
 101:             return(n);
 102:     }
 103:     return(0);
 104: }
 105: 
 106: /*
 107:  * Enter the tracing STOP state.
 108:  * In this state, the parent is
 109:  * informed and the process is able to
 110:  * receive commands from the parent.
 111:  */
 112: stop()
 113: {
 114:     register struct proc *pp, *cp;
 115: 
 116: loop:
 117:     cp = u.u_procp;
 118:     if(cp->p_ppid != 1)
 119:     for (pp = &proc[0]; pp < &proc[NPROC]; pp++)
 120:         if (pp->p_pid == cp->p_ppid) {
 121:             wakeup(pp);
 122:             cp->p_stat = SSTOP;
 123:             swtch();
 124:             if ((cp->p_flag&STRC)==0 || procxmt())
 125:                 return;
 126:             goto loop;
 127:         }
 128:     exit();
 129: }
 130: 
 131: /*
 132:  * Perform the action specified by
 133:  * the current signal.
 134:  * The usual sequence is:
 135:  *	if(issig())
 136:  *		psig();
 137:  */
 138: psig()
 139: {
 140:     register n, p;
 141:     register *rp;
 142: 
 143:     rp = u.u_procp;
 144:     n = rp->p_sig;
 145:     rp->p_sig = 0;
 146:     if((p=u.u_signal[n]) != 0) {
 147:         u.u_error = 0;
 148:         if(n != SIGINS && n != SIGTRC)
 149:             u.u_signal[n] = 0;
 150:         n = u.u_ar0[R6] - 4;
 151:         grow(n);
 152:         suword(n+2, u.u_ar0[RPS]);
 153:         suword(n, u.u_ar0[R7]);
 154:         u.u_ar0[R6] = n;
 155:         u.u_ar0[RPS] =& ~TBIT;
 156:         u.u_ar0[R7] = p;
 157:         return;
 158:     }
 159:     switch(n) {
 160: 
 161:     case SIGQIT:
 162:     case SIGINS:
 163:     case SIGTRC:
 164:     case SIGIOT:
 165:     case SIGEMT:
 166:     case SIGFPT:
 167:     case SIGBUS:
 168:     case SIGSEG:
 169:     case SIGSYS:
 170:         u.u_arg[0] = n;
 171:         if(core())
 172:             n =+ 0200;
 173:     }
 174:     u.u_arg[0] = (u.u_ar0[R0]<<8) | n;
 175:     exit();
 176: }
 177: 
 178: /*
 179:  * Create a core image on the file "core"
 180:  * If you are looking for protection glitches,
 181:  * there are probably a wealth of them here
 182:  * when this occurs to a suid command.
 183:  *
 184:  * It writes USIZE block of the
 185:  * user.h area followed by the entire
 186:  * data+stack segments.
 187:  */
 188: core()
 189: {
 190:     register s, *ip;
 191:     extern schar;
 192: 
 193:     u.u_error = 0;
 194:     u.u_dirp = "core";
 195:     ip = namei(&schar, 1);
 196:     if(ip == NULL) {
 197:         if(u.u_error)
 198:             return(0);
 199:         ip = maknode(0666);
 200:         if(ip == NULL)
 201:             return(0);
 202:     }
 203:     if(!access(ip, IWRITE) &&
 204:        (ip->i_mode&IFMT) == 0 &&
 205:        u.u_uid == u.u_ruid) {
 206:         itrunc(ip);
 207:         u.u_offset[0] = 0;
 208:         u.u_offset[1] = 0;
 209:         u.u_base = &u;
 210:         u.u_count = USIZE*64;
 211:         u.u_segflg = 1;
 212:         writei(ip);
 213:         s = u.u_procp->p_size - USIZE;
 214:         estabur(0, s, 0, 0);
 215:         u.u_base = 0;
 216:         u.u_count = s*64;
 217:         u.u_segflg = 0;
 218:         writei(ip);
 219:     }
 220:     iput(ip);
 221:     return(u.u_error==0);
 222: }
 223: 
 224: /*
 225:  * grow the stack to include the SP
 226:  * true return if successful.
 227:  */
 228: 
 229: grow(sp)
 230: char *sp;
 231: {
 232:     register a, si, i;
 233: 
 234:     if(sp >= -u.u_ssize*64)
 235:         return(0);
 236:     si = ldiv(-sp, 64) - u.u_ssize + SINCR;
 237:     if(si <= 0)
 238:         return(0);
 239:     if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep))
 240:         return(0);
 241:     expand(u.u_procp->p_size+si);
 242:     a = u.u_procp->p_addr + u.u_procp->p_size;
 243:     for(i=u.u_ssize; i; i--) {
 244:         a--;
 245:         copyseg(a-si, a);
 246:     }
 247:     for(i=si; i; i--)
 248:         clearseg(--a);
 249:     u.u_ssize =+ si;
 250:     return(1);
 251: }
 252: 
 253: /*
 254:  * sys-trace system call.
 255:  */
 256: ptrace()
 257: {
 258:     register struct proc *p;
 259: 
 260:     if (u.u_arg[2] <= 0) {
 261:         u.u_procp->p_flag =| STRC;
 262:         return;
 263:     }
 264:     for (p=proc; p < &proc[NPROC]; p++)
 265:         if (p->p_stat==SSTOP
 266:          && p->p_pid==u.u_arg[0]
 267:          && p->p_ppid==u.u_procp->p_pid)
 268:             goto found;
 269:     u.u_error = ESRCH;
 270:     return;
 271: 
 272:     found:
 273:     while (ipc.ip_lock)
 274:         sleep(&ipc, IPCPRI);
 275:     ipc.ip_lock = p->p_pid;
 276:     ipc.ip_data = u.u_ar0[R0];
 277:     ipc.ip_addr = u.u_arg[1] & ~01;
 278:     ipc.ip_req = u.u_arg[2];
 279:     p->p_flag =& ~SWTED;
 280:     setrun(p);
 281:     while (ipc.ip_req > 0)
 282:         sleep(&ipc, IPCPRI);
 283:     u.u_ar0[R0] = ipc.ip_data;
 284:     if (ipc.ip_req < 0)
 285:         u.u_error = EIO;
 286:     ipc.ip_lock = 0;
 287:     wakeup(&ipc);
 288: }
 289: 
 290: /*
 291:  * Code that the child process
 292:  * executes to implement the command
 293:  * of the parent process in tracing.
 294:  */
 295: procxmt()
 296: {
 297:     register int i;
 298:     register int *p;
 299: 
 300:     if (ipc.ip_lock != u.u_procp->p_pid)
 301:         return(0);
 302:     i = ipc.ip_req;
 303:     ipc.ip_req = 0;
 304:     wakeup(&ipc);
 305:     switch (i) {
 306: 
 307:     /* read user I */
 308:     case 1:
 309:         if (fuibyte(ipc.ip_addr) == -1)
 310:             goto error;
 311:         ipc.ip_data = fuiword(ipc.ip_addr);
 312:         break;
 313: 
 314:     /* read user D */
 315:     case 2:
 316:         if (fubyte(ipc.ip_addr) == -1)
 317:             goto error;
 318:         ipc.ip_data = fuword(ipc.ip_addr);
 319:         break;
 320: 
 321:     /* read u */
 322:     case 3:
 323:         i = ipc.ip_addr;
 324:         if (i<0 || i >= (USIZE<<6))
 325:             goto error;
 326:         ipc.ip_data = u.inta[i>>1];
 327:         break;
 328: 
 329:     /* write user I (for now, always an error) */
 330:     case 4:
 331:         if (suiword(ipc.ip_addr, 0) < 0)
 332:             goto error;
 333:         suiword(ipc.ip_addr, ipc.ip_data);
 334:         break;
 335: 
 336:     /* write user D */
 337:     case 5:
 338:         if (suword(ipc.ip_addr, 0) < 0)
 339:             goto error;
 340:         suword(ipc.ip_addr, ipc.ip_data);
 341:         break;
 342: 
 343:     /* write u */
 344:     case 6:
 345:         p = &u.inta[ipc.ip_addr>>1];
 346:         if (p >= u.u_fsav && p < &u.u_fsav[25])
 347:             goto ok;
 348:         for (i=0; i<9; i++)
 349:             if (p == &u.u_ar0[regloc[i]])
 350:                 goto ok;
 351:         goto error;
 352:     ok:
 353:         if (p == &u.u_ar0[RPS]) {
 354:             ipc.ip_data =| 0170000; /* assure user space */
 355:             ipc.ip_data =& ~0340;   /* priority 0 */
 356:         }
 357:         *p = ipc.ip_data;
 358:         break;
 359: 
 360:     /* set signal and continue */
 361:     case 7:
 362:         u.u_procp->p_sig = ipc.ip_data;
 363:         return(1);
 364: 
 365:     /* force exit */
 366:     case 8:
 367:         exit();
 368: 
 369:     default:
 370:     error:
 371:         ipc.ip_req = -1;
 372:     }
 373:     return(0);
 374: }

Defined functions

core defined in line 188; used 1 times
grow defined in line 229; used 2 times
issig defined in line 88; used 4 times
procxmt defined in line 295; used 1 times
psig defined in line 138; used 2 times
psignal defined in line 61; used 5 times
ptrace defined in line 256; never used
signal defined in line 48; used 3 times
stop defined in line 112; used 1 times
  • in line 96

Defined macros

IPCPRI defined in line 15; used 2 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1324
Valid CSS Valid XHTML 1.0 Strict