date and time created 83/06/02 15:52:54 by sam
[unix-history] / usr / src / sys / kern / kern_sig.c
CommitLineData
02c45551 1/* kern_sig.c 5.19 83/05/31 */
961945a8
SL
2
3#include "../machine/reg.h"
4#include "../machine/pte.h"
5#include "../machine/psl.h"
687880f9
BJ
6
7#include "../h/param.h"
8#include "../h/systm.h"
9#include "../h/dir.h"
10#include "../h/user.h"
687880f9
BJ
11#include "../h/inode.h"
12#include "../h/proc.h"
687880f9
BJ
13#include "../h/timeb.h"
14#include "../h/times.h"
15#include "../h/conf.h"
16#include "../h/buf.h"
17#include "../h/mount.h"
18#include "../h/text.h"
19#include "../h/seg.h"
687880f9 20#include "../h/vm.h"
687880f9 21#include "../h/acct.h"
7b0cb7cb 22#include "../h/uio.h"
68954b3a 23#include "../h/kernel.h"
4f083fd7 24#include "../h/nami.h"
687880f9 25
4147b3f6
BJ
26/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
27
28sigvec()
29{
30
31}
32
33sigblock()
34{
35
36}
37
38sigsetmask()
687880f9 39{
687880f9 40
687880f9
BJ
41}
42
4147b3f6
BJ
43sigpause()
44{
45
46}
47
48sigstack()
49{
50
51}
52
39d536e6 53#ifdef notdef
1e3738da
BJ
54kill()
55{
56
57}
39d536e6 58#endif
1e3738da
BJ
59
60killpg()
61{
3b4f6e10
SL
62 register struct a {
63 int pgrp;
64 int signo;
65 } *uap = (struct a *)u.u_ap;
1e3738da 66
88a7a62a 67 u.u_error = kill1(1, uap->signo, uap->pgrp);
1e3738da
BJ
68}
69
88a7a62a 70kill1(ispgrp, signo, who)
3b4f6e10
SL
71 int ispgrp, signo, who;
72{
73 register struct proc *p;
74 int f, priv = 0;
75
dc7d58ca 76 if (signo < 0 || signo > NSIG)
3b4f6e10
SL
77 return (EINVAL);
78 if (who > 0 && !ispgrp) {
79 p = pfind(who);
80 if (p == 0 || u.u_uid && u.u_uid != p->p_uid)
81 return (ESRCH);
dc7d58ca
SL
82 if (signo)
83 psignal(p, signo);
3b4f6e10 84 return (0);
687880f9 85 }
3b4f6e10
SL
86 if (who == -1 && u.u_uid == 0)
87 priv++, who = 0, ispgrp = 1; /* like sending to pgrp */
88 else if (who == 0) {
687880f9
BJ
89 /*
90 * Zero process id means send to my process group.
91 */
3b4f6e10
SL
92 ispgrp = 1;
93 who = u.u_procp->p_pgrp;
94 if (who == 0)
95 return (EINVAL);
687880f9 96 }
3b4f6e10 97 for (f = 0, p = proc; p < procNPROC; p++) {
687880f9
BJ
98 if (p->p_stat == NULL)
99 continue;
3b4f6e10
SL
100 if (!ispgrp) {
101 if (p->p_pid != who)
687880f9 102 continue;
3b4f6e10
SL
103 } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 ||
104 (p->p_flag&SSYS) || (priv && p == u.u_procp))
687880f9
BJ
105 continue;
106 if (u.u_uid != 0 && u.u_uid != p->p_uid &&
3b4f6e10 107 (signo != SIGCONT || !inferior(p)))
687880f9
BJ
108 continue;
109 f++;
dc7d58ca
SL
110 if (signo)
111 psignal(p, signo);
687880f9 112 }
88a7a62a 113 return (f == 0 ? ESRCH : 0);
4147b3f6 114}
687880f9
BJ
115
116/*
117 * Send the specified signal to
118 * all processes with 'pgrp' as
119 * process group.
120 * Called by tty.c for quits and
121 * interrupts.
122 */
123gsignal(pgrp, sig)
124 register int pgrp;
125{
126 register struct proc *p;
127
128 if (pgrp == 0)
129 return;
130 for(p = proc; p < procNPROC; p++)
131 if (p->p_pgrp == pgrp)
132 psignal(p, sig);
133}
134
135/*
136 * Send the specified signal to
137 * the specified process.
138 */
139psignal(p, sig)
140 register struct proc *p;
141 register int sig;
142{
143 register int s;
144 register int (*action)();
145 long sigmask;
146
147 if ((unsigned)sig >= NSIG)
148 return;
149 sigmask = (1L << (sig-1));
150
151 /*
152 * If proc is traced, always give parent a chance.
153 * Otherwise get the signal action from the bits in the proc table.
154 */
155 if (p->p_flag & STRC)
156 action = SIG_DFL;
157 else {
158 s = (p->p_siga1&sigmask) != 0;
159 s <<= 1;
160 s |= (p->p_siga0&sigmask) != 0;
161 action = (int(*)())s;
162 /*
163 * If the signal is ignored, we forget about it immediately.
164 */
165 if (action == SIG_IGN)
166 return;
167 }
168#define mask(sig) (1<<(sig-1))
169#define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU))
170 if (sig) {
171 p->p_sig |= sigmask;
172 switch (sig) {
173
174 case SIGTERM:
175 if ((p->p_flag&STRC) != 0 || action != SIG_DFL)
176 break;
177 /* fall into ... */
178
179 case SIGKILL:
180 if (p->p_nice > NZERO)
181 p->p_nice = NZERO;
182 break;
183
184 case SIGCONT:
185 p->p_sig &= ~stops;
186 break;
187
188 case SIGSTOP:
189 case SIGTSTP:
190 case SIGTTIN:
191 case SIGTTOU:
192 p->p_sig &= ~mask(SIGCONT);
193 break;
194 }
195 }
196#undef mask
197#undef stops
198 /*
199 * Defer further processing for signals which are held.
200 */
201 if (action == SIG_HOLD)
202 return;
203 s = spl6();
204 switch (p->p_stat) {
205
206 case SSLEEP:
207 /*
208 * If process is sleeping at negative priority
209 * we can't interrupt the sleep... the signal will
210 * be noticed when the process returns through
211 * trap() or syscall().
212 */
213 if (p->p_pri <= PZERO)
214 goto out;
215 /*
216 * Process is sleeping and traced... make it runnable
217 * so it can discover the signal in issig() and stop
218 * for the parent.
219 */
220 if (p->p_flag&STRC)
221 goto run;
222 switch (sig) {
223
224 case SIGSTOP:
225 case SIGTSTP:
226 case SIGTTIN:
227 case SIGTTOU:
228 /*
229 * These are the signals which by default
230 * stop a process.
231 */
232 if (action != SIG_DFL)
233 goto run;
234 /*
235 * Don't clog system with children of init
236 * stopped from the keyboard.
237 */
238 if (sig != SIGSTOP && p->p_pptr == &proc[1]) {
239 psignal(p, SIGKILL);
240 p->p_sig &= ~sigmask;
241 splx(s);
242 return;
243 }
244 /*
245 * If a child in vfork(), stopping could
246 * cause deadlock.
247 */
248 if (p->p_flag&SVFORK)
249 goto out;
250 p->p_sig &= ~sigmask;
251 p->p_cursig = sig;
252 stop(p);
253 goto out;
254
255 case SIGIO:
256 case SIGURG:
257 case SIGCHLD:
258 /*
259 * These signals are special in that they
260 * don't get propogated... if the process
261 * isn't interested, forget it.
262 */
263 if (action != SIG_DFL)
264 goto run;
265 p->p_sig &= ~sigmask; /* take it away */
266 goto out;
267
268 default:
269 /*
270 * All other signals cause the process to run
271 */
272 goto run;
273 }
274 /*NOTREACHED*/
275
276 case SSTOP:
277 /*
278 * If traced process is already stopped,
279 * then no further action is necessary.
280 */
281 if (p->p_flag&STRC)
282 goto out;
283 switch (sig) {
284
285 case SIGKILL:
286 /*
287 * Kill signal always sets processes running.
288 */
289 goto run;
290
291 case SIGCONT:
292 /*
293 * If the process catches SIGCONT, let it handle
294 * the signal itself. If it isn't waiting on
295 * an event, then it goes back to run state.
296 * Otherwise, process goes back to sleep state.
297 */
298 if (action != SIG_DFL || p->p_wchan == 0)
299 goto run;
300 p->p_stat = SSLEEP;
301 goto out;
302
303 case SIGSTOP:
304 case SIGTSTP:
305 case SIGTTIN:
306 case SIGTTOU:
307 /*
308 * Already stopped, don't need to stop again.
309 * (If we did the shell could get confused.)
310 */
311 p->p_sig &= ~sigmask; /* take it away */
312 goto out;
313
314 default:
315 /*
316 * If process is sleeping interruptibly, then
317 * unstick it so that when it is continued
318 * it can look at the signal.
319 * But don't setrun the process as its not to
320 * be unstopped by the signal alone.
321 */
322 if (p->p_wchan && p->p_pri > PZERO)
323 unsleep(p);
324 goto out;
325 }
326 /*NOTREACHED*/
327
328 default:
329 /*
330 * SRUN, SIDL, SZOMB do nothing with the signal,
331 * other than kicking ourselves if we are running.
332 * It will either never be noticed, or noticed very soon.
333 */
334 if (p == u.u_procp && !noproc)
206ecc72 335#include "../vax/mtpr.h"
687880f9
BJ
336 aston();
337 goto out;
338 }
339 /*NOTREACHED*/
340run:
341 /*
342 * Raise priority to at least PUSER.
343 */
344 if (p->p_pri > PUSER)
345 if ((p != u.u_procp || noproc) && p->p_stat == SRUN &&
346 (p->p_flag & SLOAD)) {
347 remrq(p);
348 p->p_pri = PUSER;
349 setrq(p);
350 } else
351 p->p_pri = PUSER;
352 setrun(p);
353out:
354 splx(s);
355}
356
357/*
358 * Returns true if the current
359 * process has a signal to process.
360 * The signal to process is put in p_cursig.
361 * This is asked at least once each time a process enters the
362 * system (though this can usually be done without actually
363 * calling issig by checking the pending signal masks.)
364 * A signal does not do anything
365 * directly to a process; it sets
366 * a flag that asks the process to
367 * do something to itself.
368 */
369issig()
370{
371 register struct proc *p;
372 register int sig;
373 long sigbits;
374 long sigmask;
375
376 p = u.u_procp;
377 for (;;) {
378 sigbits = p->p_sig;
379 if ((p->p_flag&STRC) == 0)
380 sigbits &= ~p->p_ignsig;
381 if (p->p_flag&SVFORK)
382#define bit(a) (1<<(a-1))
383 sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
384 if (sigbits == 0)
385 break;
386 sig = ffs((int)sigbits);
387 sigmask = 1L << (sig-1);
388 p->p_sig &= ~sigmask; /* take the signal! */
389 p->p_cursig = sig;
390 if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) {
391 /*
392 * If traced, always stop, and stay
393 * stopped until released by the parent.
394 */
395 do {
396 stop(p);
397 swtch();
398 } while (!procxmt() && p->p_flag&STRC);
399
400 /*
401 * If the traced bit got turned off,
402 * then put the signal taken above back into p_sig
403 * and go back up to the top to rescan signals.
404 * This ensures that siga0 and u_signal are consistent.
405 */
406 if ((p->p_flag&STRC) == 0) {
407 p->p_sig |= sigmask;
408 continue;
409 }
410
411 /*
412 * If parent wants us to take the signal,
413 * then it will leave it in p->p_cursig;
414 * otherwise we just look for signals again.
415 */
416 sig = p->p_cursig;
417 if (sig == 0)
418 continue;
419 }
420 switch (u.u_signal[sig]) {
421
422 case SIG_DFL:
423 /*
424 * Don't take default actions on system processes.
425 */
426 if (p->p_ppid == 0)
427 break;
428 switch (sig) {
429
430 case SIGTSTP:
431 case SIGTTIN:
432 case SIGTTOU:
433 /*
434 * Children of init aren't allowed to stop
435 * on signals from the keyboard.
436 */
437 if (p->p_pptr == &proc[1]) {
438 psignal(p, SIGKILL);
439 continue;
440 }
441 /* fall into ... */
442
443 case SIGSTOP:
444 if (p->p_flag&STRC)
445 continue;
446 stop(p);
447 swtch();
448 continue;
449
450 case SIGCONT:
451 case SIGCHLD:
452 /*
453 * These signals are normally not
454 * sent if the action is the default.
455 */
456 continue; /* == ignore */
457
458 default:
459 goto send;
460 }
461 /*NOTREACHED*/
462
463 case SIG_HOLD:
464 case SIG_IGN:
465 /*
466 * Masking above should prevent us
467 * ever trying to take action on a held
468 * or ignored signal, unless process is traced.
469 */
470 if ((p->p_flag&STRC) == 0)
471 printf("issig\n");
472 continue;
473
474 default:
475 /*
476 * This signal has an action, let
477 * psig process it.
478 */
479 goto send;
480 }
481 /*NOTREACHED*/
482 }
483 /*
484 * Didn't find a signal to send.
485 */
486 p->p_cursig = 0;
487 return (0);
488
489send:
490 /*
491 * Let psig process the signal.
492 */
493 return (sig);
494}
495
687880f9
BJ
496/*
497 * Put the argument process into the stopped
498 * state and notify the parent via wakeup and/or signal.
499 */
500stop(p)
501 register struct proc *p;
502{
503
504 p->p_stat = SSTOP;
505 p->p_flag &= ~SWTED;
506 wakeup((caddr_t)p->p_pptr);
507 /*
508 * Avoid sending signal to parent if process is traced
509 */
510 if (p->p_flag&STRC)
511 return;
512 psignal(p->p_pptr, SIGCHLD);
513}
514
515/*
516 * Perform the action specified by
517 * the current signal.
518 * The usual sequence is:
519 * if (issig())
520 * psig();
521 * The signal bit has already been cleared by issig,
522 * and the current signal number stored in p->p_cursig.
523 */
524psig()
525{
526 register struct proc *rp = u.u_procp;
527 register int n = rp->p_cursig;
528 long sigmask = 1L << (n-1);
529 register int (*action)();
530
531 if (rp->p_cursig == 0)
532 panic("psig");
533 action = u.u_signal[n];
534 if (action != SIG_DFL) {
535 if (action == SIG_IGN || action == SIG_HOLD)
536 panic("psig action");
537 u.u_error = 0;
538 if (n != SIGILL && n != SIGTRAP)
539 u.u_signal[n] = 0;
540 /*
541 * If this catch value indicates automatic holding of
542 * subsequent signals, set the hold value.
543 */
544 if (SIGISDEFER(action)) {
545 (void) spl6();
88a7a62a
SL
546 /* SIG_HOLD known to be 3 */
547 rp->p_siga0 |= sigmask;
548 rp->p_siga1 |= sigmask;
687880f9
BJ
549 u.u_signal[n] = SIG_HOLD;
550 (void) spl0();
551 action = SIGUNDEFER(action);
552 }
1e3738da 553 u.u_ru.ru_nsignals++;
687880f9
BJ
554 sendsig(action, n);
555 rp->p_cursig = 0;
556 return;
557 }
558 u.u_acflag |= AXSIG;
559 switch (n) {
560
561 case SIGILL:
562 case SIGIOT:
563 case SIGBUS:
564 case SIGQUIT:
565 case SIGTRAP:
566 case SIGEMT:
567 case SIGFPE:
568 case SIGSEGV:
569 case SIGSYS:
570 u.u_arg[0] = n;
571 if (core())
572 n += 0200;
573 }
574 exit(n);
575}
576
687880f9
BJ
577/*
578 * Create a core image on the file "core"
579 * If you are looking for protection glitches,
580 * there are probably a wealth of them here
581 * when this occurs to a suid command.
582 *
583 * It writes UPAGES block of the
584 * user.h area followed by the entire
585 * data+stack segments.
586 */
587core()
588{
589 register struct inode *ip;
590 extern schar();
591
be6bd5b8 592 if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
7b0cb7cb 593 return (0);
1e3738da
BJ
594 if (ctob(UPAGES+u.u_dsize+u.u_ssize) >=
595 u.u_rlimit[RLIMIT_CORE].rlim_cur)
687880f9
BJ
596 return (0);
597 u.u_error = 0;
598 u.u_dirp = "core";
4f083fd7 599 ip = namei(schar, CREATE, 1);
687880f9
BJ
600 if (ip == NULL) {
601 if (u.u_error)
602 return (0);
be6bd5b8 603 ip = maknode(0644);
687880f9
BJ
604 if (ip==NULL)
605 return (0);
606 }
7b0cb7cb
BJ
607 if (access(ip, IWRITE) ||
608 (ip->i_mode&IFMT) != IFREG ||
609 ip->i_nlink != 1) {
687880f9 610 u.u_error = EFAULT;
7b0cb7cb
BJ
611 goto out;
612 }
4f083fd7 613 itrunc(ip, (u_long)0);
7b0cb7cb 614 u.u_acflag |= ACORE;
e0fc9a90
BJ
615 /* if (u.u_error == 0) */
616 u.u_error = rdwri(UIO_WRITE, ip,
617 (caddr_t)&u,
618 ctob(UPAGES),
619 0, 1, (int *)0);
1edb1cf8 620 if (u.u_error == 0)
a1edc12b 621 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90
BJ
622 (caddr_t)ctob(dptov(u.u_procp, 0)),
623 ctob(u.u_dsize),
a1edc12b 624 ctob(UPAGES), 0, (int *)0);
1edb1cf8 625 if (u.u_error == 0)
a1edc12b 626 u.u_error = rdwri(UIO_WRITE, ip,
e0fc9a90
BJ
627 (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)),
628 ctob(u.u_ssize),
a1edc12b 629 ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0);
7b0cb7cb 630out:
687880f9 631 iput(ip);
7b0cb7cb 632 return (u.u_error == 0);
687880f9 633}