fix for savecore: disk drivers decrease bcount near end of partition,
[unix-history] / usr / src / sys / kern / kern_sig.c
CommitLineData
da7c5cc6 1/*
d86a61ec
KM
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
da7c5cc6 4 *
d86a61ec
KM
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
b560c158 17 * @(#)kern_sig.c 7.10 (Berkeley) %G%
da7c5cc6 18 */
961945a8 19
94368568
JB
20#include "param.h"
21#include "systm.h"
94368568 22#include "user.h"
d86a61ec 23#include "vnode.h"
94368568
JB
24#include "proc.h"
25#include "timeb.h"
26#include "times.h"
94368568
JB
27#include "buf.h"
28#include "mount.h"
29#include "text.h"
30#include "seg.h"
31#include "vm.h"
32#include "acct.h"
33#include "uio.h"
d86a61ec 34#include "file.h"
94368568 35#include "kernel.h"
687880f9 36
d301d150
KM
37#include "machine/reg.h"
38#include "machine/pte.h"
39#include "machine/psl.h"
40#include "machine/mtpr.h"
41
feff6b5a 42#define cantmask (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP))
3b2ddb34
MK
43#define stopsigmask (sigmask(SIGSTOP)|sigmask(SIGTSTP)| \
44 sigmask(SIGTTIN)|sigmask(SIGTTOU))
457aa395 45
2e143991
KM
46/*
47 * Generalized interface signal handler.
48 */
4147b3f6
BJ
49sigvec()
50{
457aa395 51 register struct a {
dd012d1e 52 int signo;
457aa395
SL
53 struct sigvec *nsv;
54 struct sigvec *osv;
dd012d1e 55 } *uap = (struct a *)u.u_ap;
457aa395
SL
56 struct sigvec vec;
57 register struct sigvec *sv;
dd012d1e 58 register int sig;
fe7f81f4 59 int bit;
dd012d1e
SL
60
61 sig = uap->signo;
457aa395 62 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
dd012d1e
SL
63 u.u_error = EINVAL;
64 return;
65 }
457aa395
SL
66 sv = &vec;
67 if (uap->osv) {
68 sv->sv_handler = u.u_signal[sig];
69 sv->sv_mask = u.u_sigmask[sig];
fe7f81f4
KM
70 bit = sigmask(sig);
71 sv->sv_flags = 0;
72 if ((u.u_sigonstack & bit) != 0)
73 sv->sv_flags |= SV_ONSTACK;
74 if ((u.u_sigintr & bit) != 0)
75 sv->sv_flags |= SV_INTERRUPT;
457aa395
SL
76 u.u_error =
77 copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
78 if (u.u_error)
79 return;
80 }
81 if (uap->nsv) {
82 u.u_error =
83 copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
84 if (u.u_error)
85 return;
86 if (sig == SIGCONT && sv->sv_handler == SIG_IGN) {
87 u.u_error = EINVAL;
88 return;
89 }
90 setsigvec(sig, sv);
91 }
dd012d1e 92}
4147b3f6 93
457aa395
SL
94setsigvec(sig, sv)
95 int sig;
96 register struct sigvec *sv;
dd012d1e
SL
97{
98 register struct proc *p;
457aa395 99 register int bit;
dd012d1e 100
feff6b5a 101 bit = sigmask(sig);
dd012d1e
SL
102 p = u.u_procp;
103 /*
104 * Change setting atomically.
105 */
feff6b5a 106 (void) splhigh();
457aa395
SL
107 u.u_signal[sig] = sv->sv_handler;
108 u.u_sigmask[sig] = sv->sv_mask &~ cantmask;
fe7f81f4
KM
109 if (sv->sv_flags & SV_INTERRUPT)
110 u.u_sigintr |= bit;
111 else
112 u.u_sigintr &= ~bit;
113 if (sv->sv_flags & SV_ONSTACK)
457aa395
SL
114 u.u_sigonstack |= bit;
115 else
116 u.u_sigonstack &= ~bit;
117 if (sv->sv_handler == SIG_IGN) {
118 p->p_sig &= ~bit; /* never to be seen again */
119 p->p_sigignore |= bit;
120 p->p_sigcatch &= ~bit;
dd012d1e 121 } else {
457aa395
SL
122 p->p_sigignore &= ~bit;
123 if (sv->sv_handler == SIG_DFL)
124 p->p_sigcatch &= ~bit;
dd012d1e 125 else
457aa395 126 p->p_sigcatch |= bit;
dd012d1e
SL
127 }
128 (void) spl0();
4147b3f6
BJ
129}
130
131sigblock()
132{
dd012d1e 133 struct a {
feff6b5a 134 int mask;
dd012d1e 135 } *uap = (struct a *)u.u_ap;
457aa395 136 register struct proc *p = u.u_procp;
4147b3f6 137
feff6b5a 138 (void) splhigh();
dd012d1e 139 u.u_r.r_val1 = p->p_sigmask;
feff6b5a 140 p->p_sigmask |= uap->mask &~ cantmask;
dd012d1e 141 (void) spl0();
4147b3f6
BJ
142}
143
144sigsetmask()
687880f9 145{
dd012d1e 146 struct a {
feff6b5a 147 int mask;
dd012d1e
SL
148 } *uap = (struct a *)u.u_ap;
149 register struct proc *p = u.u_procp;
687880f9 150
feff6b5a 151 (void) splhigh();
dd012d1e 152 u.u_r.r_val1 = p->p_sigmask;
feff6b5a 153 p->p_sigmask = uap->mask &~ cantmask;
dd012d1e 154 (void) spl0();
687880f9
BJ
155}
156
4147b3f6
BJ
157sigpause()
158{
dd012d1e 159 struct a {
feff6b5a 160 int mask;
dd012d1e
SL
161 } *uap = (struct a *)u.u_ap;
162 register struct proc *p = u.u_procp;
4147b3f6 163
dd012d1e
SL
164 /*
165 * When returning from sigpause, we want
166 * the old mask to be restored after the
167 * signal handler has finished. Thus, we
168 * save it here and mark the proc structure
169 * to indicate this (should be in u.).
170 */
171 u.u_oldmask = p->p_sigmask;
172 p->p_flag |= SOMASK;
feff6b5a 173 p->p_sigmask = uap->mask &~ cantmask;
dd012d1e
SL
174 for (;;)
175 sleep((caddr_t)&u, PSLEP);
176 /*NOTREACHED*/
4147b3f6 177}
457aa395 178#undef cantmask
4147b3f6
BJ
179
180sigstack()
181{
457aa395 182 register struct a {
457aa395
SL
183 struct sigstack *nss;
184 struct sigstack *oss;
dd012d1e 185 } *uap = (struct a *)u.u_ap;
457aa395 186 struct sigstack ss;
4147b3f6 187
457aa395
SL
188 if (uap->oss) {
189 u.u_error = copyout((caddr_t)&u.u_sigstack, (caddr_t)uap->oss,
190 sizeof (struct sigstack));
191 if (u.u_error)
192 return;
193 }
194 if (uap->nss) {
195 u.u_error =
196 copyin((caddr_t)uap->nss, (caddr_t)&ss, sizeof (ss));
197 if (u.u_error == 0)
198 u.u_sigstack = ss;
199 }
4147b3f6
BJ
200}
201
1e3738da
BJ
202kill()
203{
dd012d1e
SL
204 register struct a {
205 int pid;
206 int signo;
207 } *uap = (struct a *)u.u_ap;
7713be67 208 register struct proc *p;
1e3738da 209
7713be67
KM
210 if (uap->signo < 0 || uap->signo > NSIG) {
211 u.u_error = EINVAL;
212 return;
213 }
214 if (uap->pid > 0) {
215 /* kill single process */
216 p = pfind(uap->pid);
217 if (p == 0) {
218 u.u_error = ESRCH;
219 return;
220 }
221 if (u.u_uid && u.u_uid != p->p_uid)
222 u.u_error = EPERM;
223 else if (uap->signo)
224 psignal(p, uap->signo);
225 return;
226 }
227 switch (uap->pid) {
228 case -1: /* broadcast signal */
c52373fd 229 u.u_error = killpg1(uap->signo, 0, 1);
7713be67
KM
230 break;
231 case 0: /* signal own process group */
232 u.u_error = killpg1(uap->signo, 0, 0);
233 break;
234 default: /* negative explicit process group */
235 u.u_error = killpg1(uap->signo, -uap->pid, 0);
236 break;
237 }
238 return;
1e3738da
BJ
239}
240
241killpg()
242{
3b4f6e10 243 register struct a {
8fe87cbb 244 int pgid;
3b4f6e10
SL
245 int signo;
246 } *uap = (struct a *)u.u_ap;
1e3738da 247
7713be67
KM
248 if (uap->signo < 0 || uap->signo > NSIG) {
249 u.u_error = EINVAL;
250 return;
251 }
8fe87cbb 252 u.u_error = killpg1(uap->signo, uap->pgid, 0);
1e3738da
BJ
253}
254
dd012d1e
SL
255/* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */
256
8fe87cbb
MT
257killpg1(signo, pgid, all)
258 int signo, pgid, all;
3b4f6e10
SL
259{
260 register struct proc *p;
8fe87cbb
MT
261 struct pgrp *pgrp;
262 int f = 0, error = 0;
3b4f6e10 263
8fe87cbb
MT
264
265 if (all)
266 /*
267 * broadcast
687880f9 268 */
8fe87cbb
MT
269 for (p = allproc; p != NULL; p = p->p_nxt) {
270 if (p->p_ppid == 0 || p->p_flag&SSYS ||
271 p == u.u_procp ||
272 (u.u_uid && u.u_uid != p->p_uid &&
273 !(signo == SIGCONT && inferior(p))))
274 continue;
275 f++;
276 if (signo)
277 psignal(p, signo);
278 }
279 else {
280 if (pgid == 0)
281 /*
282 * zero pgid means send to my process group.
283 */
284 pgrp = u.u_procp->p_pgrp;
285 else {
286 pgrp = pgfind(pgid);
287 if (pgrp == NULL)
288 return(ESRCH);
289 }
290 if (!(pgrp->pg_jobc) &&
291 (signo==SIGTTIN || signo==SIGTTOU || signo==SIGTSTP))
292 return(EPERM);
293 for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt) {
294 if (p->p_ppid == 0 || p->p_flag&SSYS)
295 continue;
296 if (u.u_uid && u.u_uid != p->p_uid &&
297 !(signo == SIGCONT && inferior(p))) {
c52373fd 298 error = EPERM;
8fe87cbb
MT
299 continue;
300 }
301 f++;
302 if (signo)
303 psignal(p, signo);
7713be67 304 }
687880f9 305 }
8db20a41 306 return (error ? error : (f == 0 ? ESRCH : 0));
4147b3f6 307}
687880f9
BJ
308
309/*
310 * Send the specified signal to
8fe87cbb 311 * all processes with 'pgid' as
687880f9 312 * process group.
687880f9 313 */
8fe87cbb
MT
314gsignal(pgid, sig)
315{
316 register struct pgrp *pgrp;
8fe87cbb
MT
317
318 if (!pgid)
319 return;
320 if ((pgrp = pgfind(pgid)) == NULL)
321 return;
322 pgsignal(pgrp, sig);
323}
324
325pgsignal(pgrp, sig)
326 register struct pgrp *pgrp;
687880f9
BJ
327{
328 register struct proc *p;
329
8fe87cbb
MT
330 if (!(pgrp->pg_jobc) &&
331 (sig==SIGTTIN || sig==SIGTTOU || sig==SIGTSTP))
687880f9 332 return;
8fe87cbb
MT
333 for (p = pgrp->pg_mem; p != NULL; p = p->p_pgrpnxt)
334 psignal(p, sig);
687880f9
BJ
335}
336
337/*
338 * Send the specified signal to
339 * the specified process.
340 */
341psignal(p, sig)
342 register struct proc *p;
343 register int sig;
344{
345 register int s;
346 register int (*action)();
feff6b5a 347 int mask;
687880f9
BJ
348
349 if ((unsigned)sig >= NSIG)
350 return;
feff6b5a 351 mask = sigmask(sig);
687880f9
BJ
352
353 /*
354 * If proc is traced, always give parent a chance.
687880f9
BJ
355 */
356 if (p->p_flag & STRC)
357 action = SIG_DFL;
358 else {
687880f9 359 /*
dd012d1e
SL
360 * If the signal is being ignored,
361 * then we forget about it immediately.
687880f9 362 */
feff6b5a 363 if (p->p_sigignore & mask)
687880f9 364 return;
feff6b5a 365 if (p->p_sigmask & mask)
dd012d1e 366 action = SIG_HOLD;
feff6b5a 367 else if (p->p_sigcatch & mask)
dd012d1e
SL
368 action = SIG_CATCH;
369 else
370 action = SIG_DFL;
687880f9 371 }
687880f9 372 if (sig) {
687880f9
BJ
373 switch (sig) {
374
375 case SIGTERM:
dd012d1e 376 if ((p->p_flag&STRC) || action != SIG_DFL)
687880f9
BJ
377 break;
378 /* fall into ... */
379
380 case SIGKILL:
381 if (p->p_nice > NZERO)
382 p->p_nice = NZERO;
383 break;
384
385 case SIGCONT:
3b2ddb34 386 p->p_sig &= ~stopsigmask;
687880f9
BJ
387 break;
388
687880f9
BJ
389 case SIGTSTP:
390 case SIGTTIN:
391 case SIGTTOU:
8fe87cbb
MT
392 /*FALLTHROUGH*/
393 case SIGSTOP:
feff6b5a 394 p->p_sig &= ~sigmask(SIGCONT);
687880f9
BJ
395 break;
396 }
8fe87cbb 397 p->p_sig |= mask;
687880f9 398 }
687880f9
BJ
399 /*
400 * Defer further processing for signals which are held.
401 */
402 if (action == SIG_HOLD)
403 return;
feff6b5a 404 s = splhigh();
687880f9
BJ
405 switch (p->p_stat) {
406
407 case SSLEEP:
408 /*
409 * If process is sleeping at negative priority
410 * we can't interrupt the sleep... the signal will
411 * be noticed when the process returns through
412 * trap() or syscall().
413 */
414 if (p->p_pri <= PZERO)
415 goto out;
416 /*
417 * Process is sleeping and traced... make it runnable
418 * so it can discover the signal in issig() and stop
419 * for the parent.
420 */
421 if (p->p_flag&STRC)
422 goto run;
423 switch (sig) {
424
425 case SIGSTOP:
426 case SIGTSTP:
427 case SIGTTIN:
428 case SIGTTOU:
429 /*
430 * These are the signals which by default
431 * stop a process.
432 */
433 if (action != SIG_DFL)
434 goto run;
687880f9
BJ
435 /*
436 * If a child in vfork(), stopping could
437 * cause deadlock.
438 */
439 if (p->p_flag&SVFORK)
440 goto out;
feff6b5a 441 p->p_sig &= ~mask;
687880f9 442 p->p_cursig = sig;
ad6c75cb 443 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
444 stop(p);
445 goto out;
446
447 case SIGIO:
448 case SIGURG:
449 case SIGCHLD:
434b302a 450 case SIGWINCH:
687880f9
BJ
451 /*
452 * These signals are special in that they
453 * don't get propogated... if the process
454 * isn't interested, forget it.
455 */
456 if (action != SIG_DFL)
457 goto run;
feff6b5a 458 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
459 goto out;
460
461 default:
462 /*
463 * All other signals cause the process to run
464 */
465 goto run;
466 }
467 /*NOTREACHED*/
468
469 case SSTOP:
470 /*
471 * If traced process is already stopped,
472 * then no further action is necessary.
473 */
474 if (p->p_flag&STRC)
475 goto out;
476 switch (sig) {
477
478 case SIGKILL:
479 /*
480 * Kill signal always sets processes running.
481 */
482 goto run;
483
484 case SIGCONT:
485 /*
486 * If the process catches SIGCONT, let it handle
487 * the signal itself. If it isn't waiting on
488 * an event, then it goes back to run state.
489 * Otherwise, process goes back to sleep state.
490 */
491 if (action != SIG_DFL || p->p_wchan == 0)
492 goto run;
493 p->p_stat = SSLEEP;
494 goto out;
495
496 case SIGSTOP:
497 case SIGTSTP:
498 case SIGTTIN:
499 case SIGTTOU:
500 /*
501 * Already stopped, don't need to stop again.
502 * (If we did the shell could get confused.)
503 */
feff6b5a 504 p->p_sig &= ~mask; /* take it away */
687880f9
BJ
505 goto out;
506
507 default:
508 /*
509 * If process is sleeping interruptibly, then
510 * unstick it so that when it is continued
511 * it can look at the signal.
512 * But don't setrun the process as its not to
513 * be unstopped by the signal alone.
514 */
515 if (p->p_wchan && p->p_pri > PZERO)
516 unsleep(p);
517 goto out;
518 }
519 /*NOTREACHED*/
520
521 default:
522 /*
523 * SRUN, SIDL, SZOMB do nothing with the signal,
524 * other than kicking ourselves if we are running.
525 * It will either never be noticed, or noticed very soon.
526 */
527 if (p == u.u_procp && !noproc)
528 aston();
529 goto out;
530 }
531 /*NOTREACHED*/
532run:
533 /*
534 * Raise priority to at least PUSER.
535 */
536 if (p->p_pri > PUSER)
e4f89871 537 p->p_pri = PUSER;
687880f9
BJ
538 setrun(p);
539out:
540 splx(s);
541}
542
543/*
544 * Returns true if the current
545 * process has a signal to process.
546 * The signal to process is put in p_cursig.
547 * This is asked at least once each time a process enters the
548 * system (though this can usually be done without actually
549 * calling issig by checking the pending signal masks.)
550 * A signal does not do anything
551 * directly to a process; it sets
552 * a flag that asks the process to
553 * do something to itself.
554 */
555issig()
556{
557 register struct proc *p;
558 register int sig;
feff6b5a 559 int sigbits, mask;
687880f9
BJ
560
561 p = u.u_procp;
562 for (;;) {
f99e4a3a 563 sigbits = p->p_sig &~ p->p_sigmask;
687880f9 564 if ((p->p_flag&STRC) == 0)
f99e4a3a 565 sigbits &= ~p->p_sigignore;
687880f9 566 if (p->p_flag&SVFORK)
3b2ddb34 567 sigbits &= ~stopsigmask;
687880f9
BJ
568 if (sigbits == 0)
569 break;
8011f5df 570 sig = ffs((long)sigbits);
feff6b5a
JB
571 mask = sigmask(sig);
572 p->p_sig &= ~mask; /* take the signal! */
687880f9 573 p->p_cursig = sig;
dd012d1e 574 if (p->p_flag&STRC && (p->p_flag&SVFORK) == 0) {
687880f9
BJ
575 /*
576 * If traced, always stop, and stay
577 * stopped until released by the parent.
578 */
ad6c75cb 579 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
580 do {
581 stop(p);
582 swtch();
583 } while (!procxmt() && p->p_flag&STRC);
584
585 /*
f99e4a3a
SL
586 * If the traced bit got turned off,
587 * then put the signal taken above back into p_sig
588 * and go back up to the top to rescan signals.
589 * This ensures that p_sig* and u_signal are consistent.
687880f9 590 */
f99e4a3a 591 if ((p->p_flag&STRC) == 0) {
feff6b5a 592 p->p_sig |= mask;
687880f9
BJ
593 continue;
594 }
595
596 /*
597 * If parent wants us to take the signal,
598 * then it will leave it in p->p_cursig;
599 * otherwise we just look for signals again.
600 */
601 sig = p->p_cursig;
602 if (sig == 0)
603 continue;
f99e4a3a
SL
604
605 /*
606 * If signal is being masked put it back
607 * into p_sig and look for other signals.
608 */
feff6b5a
JB
609 mask = sigmask(sig);
610 if (p->p_sigmask & mask) {
611 p->p_sig |= mask;
f99e4a3a
SL
612 continue;
613 }
687880f9 614 }
a488db1a 615 switch ((int)u.u_signal[sig]) {
687880f9
BJ
616
617 case SIG_DFL:
618 /*
619 * Don't take default actions on system processes.
620 */
621 if (p->p_ppid == 0)
622 break;
623 switch (sig) {
624
625 case SIGTSTP:
626 case SIGTTIN:
627 case SIGTTOU:
687880f9
BJ
628 case SIGSTOP:
629 if (p->p_flag&STRC)
630 continue;
ad6c75cb 631 psignal(p->p_pptr, SIGCHLD);
687880f9
BJ
632 stop(p);
633 swtch();
634 continue;
635
636 case SIGCONT:
637 case SIGCHLD:
dd012d1e 638 case SIGURG:
457aa395 639 case SIGIO:
434b302a 640 case SIGWINCH:
687880f9
BJ
641 /*
642 * These signals are normally not
643 * sent if the action is the default.
644 */
645 continue; /* == ignore */
646
647 default:
648 goto send;
649 }
650 /*NOTREACHED*/
651
652 case SIG_HOLD:
653 case SIG_IGN:
654 /*
655 * Masking above should prevent us
656 * ever trying to take action on a held
657 * or ignored signal, unless process is traced.
658 */
659 if ((p->p_flag&STRC) == 0)
660 printf("issig\n");
661 continue;
662
663 default:
664 /*
665 * This signal has an action, let
666 * psig process it.
667 */
668 goto send;
669 }
670 /*NOTREACHED*/
671 }
672 /*
673 * Didn't find a signal to send.
674 */
675 p->p_cursig = 0;
676 return (0);
677
678send:
679 /*
680 * Let psig process the signal.
681 */
682 return (sig);
683}
684
687880f9
BJ
685/*
686 * Put the argument process into the stopped
ad6c75cb
MK
687 * state and notify the parent via wakeup.
688 * Signals are handled elsewhere.
687880f9
BJ
689 */
690stop(p)
691 register struct proc *p;
692{
693
694 p->p_stat = SSTOP;
695 p->p_flag &= ~SWTED;
696 wakeup((caddr_t)p->p_pptr);
687880f9
BJ
697}
698
699/*
700 * Perform the action specified by
701 * the current signal.
702 * The usual sequence is:
703 * if (issig())
704 * psig();
705 * The signal bit has already been cleared by issig,
706 * and the current signal number stored in p->p_cursig.
707 */
708psig()
709{
dd012d1e
SL
710 register struct proc *p = u.u_procp;
711 register int sig = p->p_cursig;
feff6b5a 712 int mask = sigmask(sig), returnmask;
687880f9
BJ
713 register int (*action)();
714
dd012d1e 715 if (sig == 0)
687880f9 716 panic("psig");
dd012d1e 717 action = u.u_signal[sig];
687880f9 718 if (action != SIG_DFL) {
feff6b5a 719 if (action == SIG_IGN || (p->p_sigmask & mask))
687880f9
BJ
720 panic("psig action");
721 u.u_error = 0;
687880f9 722 /*
dd012d1e
SL
723 * Set the new mask value and also defer further
724 * occurences of this signal (unless we're simulating
725 * the old signal facilities).
726 *
727 * Special case: user has done a sigpause. Here the
728 * current mask is not of interest, but rather the
729 * mask from before the sigpause is what we want restored
730 * after the signal processing is completed.
687880f9 731 */
feff6b5a 732 (void) splhigh();
dd012d1e
SL
733 if (p->p_flag & SOUSIG) {
734 if (sig != SIGILL && sig != SIGTRAP) {
735 u.u_signal[sig] = SIG_DFL;
feff6b5a 736 p->p_sigcatch &= ~mask;
dd012d1e 737 }
feff6b5a 738 mask = 0;
687880f9 739 }
dd012d1e
SL
740 if (p->p_flag & SOMASK) {
741 returnmask = u.u_oldmask;
742 p->p_flag &= ~SOMASK;
743 } else
744 returnmask = p->p_sigmask;
feff6b5a 745 p->p_sigmask |= u.u_sigmask[sig] | mask;
dd012d1e 746 (void) spl0();
1e3738da 747 u.u_ru.ru_nsignals++;
dd012d1e
SL
748 sendsig(action, sig, returnmask);
749 p->p_cursig = 0;
687880f9
BJ
750 return;
751 }
752 u.u_acflag |= AXSIG;
dd012d1e 753 switch (sig) {
687880f9
BJ
754
755 case SIGILL:
756 case SIGIOT:
757 case SIGBUS:
758 case SIGQUIT:
759 case SIGTRAP:
760 case SIGEMT:
761 case SIGFPE:
762 case SIGSEGV:
763 case SIGSYS:
dd012d1e 764 u.u_arg[0] = sig;
d86a61ec 765 if (core() == 0)
dd012d1e 766 sig += 0200;
687880f9 767 }
dd012d1e 768 exit(sig);
687880f9
BJ
769}
770
687880f9
BJ
771/*
772 * Create a core image on the file "core"
773 * If you are looking for protection glitches,
774 * there are probably a wealth of them here
775 * when this occurs to a suid command.
776 *
777 * It writes UPAGES block of the
778 * user.h area followed by the entire
779 * data+stack segments.
780 */
781core()
782{
c4ec2128 783 register struct vnode *vp;
715baff1 784 register struct nameidata *ndp = &u.u_nd;
d86a61ec
KM
785 struct vattr vattr;
786 int error;
687880f9 787
be6bd5b8 788 if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid)
d86a61ec
KM
789 return (EFAULT);
790 if (ctob(UPAGES + u.u_dsize + u.u_ssize) >=
1e3738da 791 u.u_rlimit[RLIMIT_CORE].rlim_cur)
d86a61ec
KM
792 return (EFAULT);
793 if (u.u_procp->p_textp) {
c4ec2128 794 VOP_LOCK(u.u_procp->p_textp->x_vptr);
b560c158 795 error = VOP_ACCESS(u.u_procp->p_textp->x_vptr, VREAD, u.u_cred);
c4ec2128 796 VOP_UNLOCK(u.u_procp->p_textp->x_vptr);
d86a61ec
KM
797 if (error)
798 return (EFAULT);
799 }
715baff1
KM
800 ndp->ni_segflg = UIO_SYSSPACE;
801 ndp->ni_dirp = "core";
d86a61ec
KM
802 if (error = vn_open(ndp, FCREAT|FWRITE, 0644))
803 return (error);
804 vp = ndp->ni_vp;
4493085b 805 VOP_LOCK(vp);
d86a61ec 806 if (vp->v_type != VREG ||
c4ec2128 807 VOP_GETATTR(vp, &vattr, u.u_cred) ||
d86a61ec 808 vattr.va_nlink != 1) {
4493085b
KM
809 vput(vp);
810 return (EFAULT);
7b0cb7cb 811 }
728df0db
SL
812#ifdef MMAP
813 { register int fd;
4493085b 814 /* unmap funky devices in the user's address space */
728df0db
SL
815 for (fd = 0; fd < u.u_lastfile; fd++)
816 if (u.u_ofile[fd] && (u.u_pofile[fd] & UF_MAPPED))
817 munmapfd(fd);
818 }
819#endif
d86a61ec
KM
820 vattr_null(&vattr);
821 vattr.va_size = 0;
c4ec2128 822 VOP_SETATTR(vp, &vattr, u.u_cred);
7b0cb7cb 823 u.u_acflag |= ACORE;
d86a61ec 824 error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&u, ctob(UPAGES), (off_t)0,
4493085b 825 UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
d86a61ec
KM
826 if (error == 0)
827 error = vn_rdwr(UIO_WRITE, vp,
e0fc9a90 828 (caddr_t)ctob(dptov(u.u_procp, 0)),
4493085b
KM
829 (int)ctob(u.u_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
830 IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
d86a61ec
KM
831 if (error == 0)
832 error = vn_rdwr(UIO_WRITE, vp,
e0fc9a90 833 (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)),
8011f5df 834 (int)ctob(u.u_ssize),
4493085b
KM
835 (off_t)ctob(UPAGES) + ctob(u.u_dsize), UIO_USERSPACE,
836 IO_NODELOCKED|IO_UNIT, ndp->ni_cred, (int *)0);
837 vput(vp);
d86a61ec 838 return (error);
687880f9 839}