home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / ken / sig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  6.0 KB  |  375 lines

  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. }
  375.