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
psig
defined in line
138; used 2 times
stop
defined in line
112; used 1 times
Defined macros