Use correct value for _NSIG

User processes can send signals with number up to _NSIG. There are a few
signal numbers above that used by the kernel, but should explicitly not
be included in the range or range checks in PM will fail.

The system processes use a different version of sigaddset, sigdelset,
sigemptyset, sigfillset, and sigismember which does not include a range
check on signal numbers (as opposed to the normal functions used by normal
processes).

This patch unbreaks test37 when the boot image is compiled with GCC/Clang.
This commit is contained in:
Thomas Veerman 2012-01-16 11:42:29 +00:00
parent a282e942bf
commit a6d0ee24c3
8 changed files with 61 additions and 57 deletions

View File

@ -374,7 +374,7 @@ PUBLIC void send_sig(endpoint_t ep, int sig_nr)
panic("send_sig to empty process: %d", ep); panic("send_sig to empty process: %d", ep);
rp = proc_addr(proc_nr); rp = proc_addr(proc_nr);
(void) sigaddset(&priv(rp)->s_sig_pending, sig_nr); sigaddset(&priv(rp)->s_sig_pending, sig_nr);
mini_notify(proc_addr(SYSTEM), rp->p_endpoint); mini_notify(proc_addr(SYSTEM), rp->p_endpoint);
} }
@ -425,14 +425,14 @@ int sig_nr; /* signal to be sent */
panic("cause_sig: sig manager %d gets lethal signal %d for itself", panic("cause_sig: sig manager %d gets lethal signal %d for itself",
rp->p_endpoint, sig_nr); rp->p_endpoint, sig_nr);
} }
(void) sigaddset(&priv(rp)->s_sig_pending, sig_nr); sigaddset(&priv(rp)->s_sig_pending, sig_nr);
send_sig(rp->p_endpoint, SIGKSIGSM); send_sig(rp->p_endpoint, SIGKSIGSM);
return; return;
} }
/* Check if the signal is already pending. Process it otherwise. */ /* Check if the signal is already pending. Process it otherwise. */
if (! sigismember(&rp->p_pending, sig_nr)) { if (! sigismember(&rp->p_pending, sig_nr)) {
(void) sigaddset(&rp->p_pending, sig_nr); sigaddset(&rp->p_pending, sig_nr);
if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */ if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */
RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING); RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING);
send_sig(sig_mgr, SIGKSIG); send_sig(sig_mgr, SIGKSIG);

View File

@ -79,11 +79,19 @@ int __libc_thr_sigsetmask(int, const sigset_t * __restrict,
#ifndef __LIBC12_SOURCE__ #ifndef __LIBC12_SOURCE__
int sigaction(int, const struct sigaction * __restrict, int sigaction(int, const struct sigaction * __restrict,
struct sigaction * __restrict) __RENAME(__sigaction14); struct sigaction * __restrict) __RENAME(__sigaction14);
#if defined(__minix) && defined(_SYSTEM)
#define sigaddset(set, sig) __sigaddset((set), (sig))
#define sigdelset(set, sig) __sigdelset((set), (sig))
#define sigemptyset(set) __sigemptyset((set))
#define sigfillset(set) __sigfillset((set))
#define sigismember(set, sig) __sigismember((set), (sig))
#else
int sigaddset(sigset_t *, int) __RENAME(__sigaddset14); int sigaddset(sigset_t *, int) __RENAME(__sigaddset14);
int sigdelset(sigset_t *, int) __RENAME(__sigdelset14); int sigdelset(sigset_t *, int) __RENAME(__sigdelset14);
int sigemptyset(sigset_t *) __RENAME(__sigemptyset14); int sigemptyset(sigset_t *) __RENAME(__sigemptyset14);
int sigfillset(sigset_t *) __RENAME(__sigfillset14); int sigfillset(sigset_t *) __RENAME(__sigfillset14);
int sigismember(const sigset_t *, int) __RENAME(__sigismember14); int sigismember(const sigset_t *, int) __RENAME(__sigismember14);
#endif
int sigpending(sigset_t *) __RENAME(__sigpending14); int sigpending(sigset_t *) __RENAME(__sigpending14);
int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict) int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict)
__RENAME(__sigprocmask14); __RENAME(__sigprocmask14);
@ -107,6 +115,7 @@ int *__errno(void);
#define ___errno (*__errno()) #define ___errno (*__errno())
#endif #endif
#if !defined(__minix) || !defined(_SYSTEM)
__c99inline int __c99inline int
sigaddset(sigset_t *set, int signo) sigaddset(sigset_t *set, int signo)
{ {
@ -152,6 +161,7 @@ sigfillset(sigset_t *set)
__sigfillset(set); __sigfillset(set);
return (0); return (0);
} }
#endif /* !defined(__minix) || !defined(_SYSTEM) */
#endif /* __c99inline */ #endif /* __c99inline */
#endif /* !__LIBC12_SOURCE__ */ #endif /* !__LIBC12_SOURCE__ */

View File

@ -4,14 +4,8 @@
#include <sys/featuretest.h> #include <sys/featuretest.h>
#include <sys/sigtypes.h> #include <sys/sigtypes.h>
#ifdef _SYSTEM #define _NSIG 26
#define _NSIG 31
#else
#define _NSIG 27
#endif
#if defined(_NETBSD_SOURCE)
#define NSIG _NSIG #define NSIG _NSIG
#endif /* _NETBSD_SOURCE */
/* Regular signals. */ /* Regular signals. */

View File

@ -182,9 +182,9 @@ vir_bytes pc;
*/ */
for (sn = 1; sn < _NSIG; sn++) { for (sn = 1; sn < _NSIG; sn++) {
if (sigismember(&rmp->mp_catch, sn)) { if (sigismember(&rmp->mp_catch, sn)) {
(void) sigdelset(&rmp->mp_catch, sn); sigdelset(&rmp->mp_catch, sn);
rmp->mp_sigact[sn].sa_handler = SIG_DFL; rmp->mp_sigact[sn].sa_handler = SIG_DFL;
(void) sigemptyset(&rmp->mp_sigact[sn].sa_mask); sigemptyset(&rmp->mp_sigact[sn].sa_mask);
} }
} }

View File

@ -488,7 +488,7 @@ PUBLIC int do_waitpid()
*/ */
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember(&rp->mp_sigtrace, i)) { if (sigismember(&rp->mp_sigtrace, i)) {
(void) sigdelset(&rp->mp_sigtrace, i); sigdelset(&rp->mp_sigtrace, i);
mp->mp_reply.reply_res2 = mp->mp_reply.reply_res2 =
0177 | (i << 8); 0177 | (i << 8);

View File

@ -213,15 +213,15 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
/* Build the set of signals which cause core dumps, and the set of signals /* Build the set of signals which cause core dumps, and the set of signals
* that are by default ignored. * that are by default ignored.
*/ */
(void) sigemptyset(&core_sset); sigemptyset(&core_sset);
for (sig_ptr = core_sigs; sig_ptr < core_sigs+sizeof(core_sigs); sig_ptr++) for (sig_ptr = core_sigs; sig_ptr < core_sigs+sizeof(core_sigs); sig_ptr++)
(void) sigaddset(&core_sset, *sig_ptr); sigaddset(&core_sset, *sig_ptr);
(void) sigemptyset(&ign_sset); sigemptyset(&ign_sset);
for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++) for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++)
(void) sigaddset(&ign_sset, *sig_ptr); sigaddset(&ign_sset, *sig_ptr);
(void) sigemptyset(&noign_sset); sigemptyset(&noign_sset);
for (sig_ptr = noign_sigs; sig_ptr < noign_sigs+sizeof(noign_sigs); sig_ptr++) for (sig_ptr = noign_sigs; sig_ptr < noign_sigs+sizeof(noign_sigs); sig_ptr++)
(void) sigaddset(&noign_sset, *sig_ptr); sigaddset(&noign_sset, *sig_ptr);
/* Obtain a copy of the boot monitor parameters and the kernel info struct. /* Obtain a copy of the boot monitor parameters and the kernel info struct.
* Parse the list of free memory chunks. This list is what the boot monitor * Parse the list of free memory chunks. This list is what the boot monitor

View File

@ -65,20 +65,20 @@ PUBLIC int do_sigaction()
if (r != OK) return(r); if (r != OK) return(r);
if (svec.sa_handler == SIG_IGN) { if (svec.sa_handler == SIG_IGN) {
(void) sigaddset(&mp->mp_ignore, m_in.sig_nr); sigaddset(&mp->mp_ignore, m_in.sig_nr);
(void) sigdelset(&mp->mp_sigpending, m_in.sig_nr); sigdelset(&mp->mp_sigpending, m_in.sig_nr);
(void) sigdelset(&mp->mp_ksigpending, m_in.sig_nr); sigdelset(&mp->mp_ksigpending, m_in.sig_nr);
(void) sigdelset(&mp->mp_catch, m_in.sig_nr); sigdelset(&mp->mp_catch, m_in.sig_nr);
} else if (svec.sa_handler == SIG_DFL) { } else if (svec.sa_handler == SIG_DFL) {
(void) sigdelset(&mp->mp_ignore, m_in.sig_nr); sigdelset(&mp->mp_ignore, m_in.sig_nr);
(void) sigdelset(&mp->mp_catch, m_in.sig_nr); sigdelset(&mp->mp_catch, m_in.sig_nr);
} else { } else {
(void) sigdelset(&mp->mp_ignore, m_in.sig_nr); sigdelset(&mp->mp_ignore, m_in.sig_nr);
(void) sigaddset(&mp->mp_catch, m_in.sig_nr); sigaddset(&mp->mp_catch, m_in.sig_nr);
} }
mp->mp_sigact[m_in.sig_nr].sa_handler = svec.sa_handler; mp->mp_sigact[m_in.sig_nr].sa_handler = svec.sa_handler;
(void) sigdelset(&svec.sa_mask, SIGKILL); sigdelset(&svec.sa_mask, SIGKILL);
(void) sigdelset(&svec.sa_mask, SIGSTOP); sigdelset(&svec.sa_mask, SIGSTOP);
mp->mp_sigact[m_in.sig_nr].sa_mask = svec.sa_mask; mp->mp_sigact[m_in.sig_nr].sa_mask = svec.sa_mask;
mp->mp_sigact[m_in.sig_nr].sa_flags = svec.sa_flags; mp->mp_sigact[m_in.sig_nr].sa_flags = svec.sa_flags;
mp->mp_sigreturn = (vir_bytes) m_in.sig_ret; mp->mp_sigreturn = (vir_bytes) m_in.sig_ret;
@ -116,25 +116,25 @@ PUBLIC int do_sigprocmask()
switch (m_in.sig_how) { switch (m_in.sig_how) {
case SIG_BLOCK: case SIG_BLOCK:
(void) sigdelset((sigset_t *)&m_in.sig_set, SIGKILL); sigdelset((sigset_t *)&m_in.sig_set, SIGKILL);
(void) sigdelset((sigset_t *)&m_in.sig_set, SIGSTOP); sigdelset((sigset_t *)&m_in.sig_set, SIGSTOP);
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember((sigset_t *)&m_in.sig_set, i)) if (sigismember((sigset_t *)&m_in.sig_set, i))
(void) sigaddset(&mp->mp_sigmask, i); sigaddset(&mp->mp_sigmask, i);
} }
break; break;
case SIG_UNBLOCK: case SIG_UNBLOCK:
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember((sigset_t *)&m_in.sig_set, i)) if (sigismember((sigset_t *)&m_in.sig_set, i))
(void) sigdelset(&mp->mp_sigmask, i); sigdelset(&mp->mp_sigmask, i);
} }
check_pending(mp); check_pending(mp);
break; break;
case SIG_SETMASK: case SIG_SETMASK:
(void) sigdelset((sigset_t *) &m_in.sig_set, SIGKILL); sigdelset((sigset_t *) &m_in.sig_set, SIGKILL);
(void) sigdelset((sigset_t *) &m_in.sig_set, SIGSTOP); sigdelset((sigset_t *) &m_in.sig_set, SIGSTOP);
mp->mp_sigmask = (sigset_t) m_in.sig_set; mp->mp_sigmask = (sigset_t) m_in.sig_set;
check_pending(mp); check_pending(mp);
break; break;
@ -156,8 +156,8 @@ PUBLIC int do_sigsuspend()
{ {
mp->mp_sigmask2 = mp->mp_sigmask; /* save the old mask */ mp->mp_sigmask2 = mp->mp_sigmask; /* save the old mask */
mp->mp_sigmask = (sigset_t) m_in.sig_set; mp->mp_sigmask = (sigset_t) m_in.sig_set;
(void) sigdelset(&mp->mp_sigmask, SIGKILL); sigdelset(&mp->mp_sigmask, SIGKILL);
(void) sigdelset(&mp->mp_sigmask, SIGSTOP); sigdelset(&mp->mp_sigmask, SIGSTOP);
mp->mp_flags |= SIGSUSPENDED; mp->mp_flags |= SIGSUSPENDED;
check_pending(mp); check_pending(mp);
return(SUSPEND); return(SUSPEND);
@ -175,8 +175,8 @@ PUBLIC int do_sigreturn()
int r; int r;
mp->mp_sigmask = (sigset_t) m_in.sig_set; mp->mp_sigmask = (sigset_t) m_in.sig_set;
(void) sigdelset(&mp->mp_sigmask, SIGKILL); sigdelset(&mp->mp_sigmask, SIGKILL);
(void) sigdelset(&mp->mp_sigmask, SIGSTOP); sigdelset(&mp->mp_sigmask, SIGSTOP);
r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context); r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context);
check_pending(mp); check_pending(mp);
@ -339,7 +339,7 @@ int ksig; /* non-zero means signal comes from kernel */
* the process itself could block/ignore debugger signals. * the process itself could block/ignore debugger signals.
*/ */
(void) sigaddset(&rmp->mp_sigtrace, signo); sigaddset(&rmp->mp_sigtrace, signo);
if (!(rmp->mp_flags & STOPPED)) if (!(rmp->mp_flags & STOPPED))
stop_proc(rmp, signo); /* a signal causes it to stop */ stop_proc(rmp, signo); /* a signal causes it to stop */
@ -349,9 +349,9 @@ int ksig; /* non-zero means signal comes from kernel */
#endif #endif
if (rmp->mp_flags & VFS_CALL) { if (rmp->mp_flags & VFS_CALL) {
(void) sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) if(ksig)
(void) sigaddset(&rmp->mp_ksigpending, signo); sigaddset(&rmp->mp_ksigpending, signo);
if (!(rmp->mp_flags & PM_SIG_PENDING)) { if (!(rmp->mp_flags & PM_SIG_PENDING)) {
/* No delay calls: VFS_CALL implies the process called us. */ /* No delay calls: VFS_CALL implies the process called us. */
@ -410,9 +410,9 @@ int ksig; /* non-zero means signal comes from kernel */
} }
if (!badignore && sigismember(&rmp->mp_sigmask, signo)) { if (!badignore && sigismember(&rmp->mp_sigmask, signo)) {
/* Signal should be blocked. */ /* Signal should be blocked. */
(void) sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) if(ksig)
(void) sigaddset(&rmp->mp_ksigpending, signo); sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
@ -422,9 +422,9 @@ int ksig; /* non-zero means signal comes from kernel */
* (except SIGKILL) in order not to confuse the debugger. The signals * (except SIGKILL) in order not to confuse the debugger. The signals
* will be delivered using the check_pending() calls in do_trace(). * will be delivered using the check_pending() calls in do_trace().
*/ */
(void) sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) if(ksig)
(void) sigaddset(&rmp->mp_ksigpending, signo); sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
#endif /* USE_TRACE */ #endif /* USE_TRACE */
@ -438,9 +438,9 @@ int ksig; /* non-zero means signal comes from kernel */
if (!(rmp->mp_flags & UNPAUSED)) { if (!(rmp->mp_flags & UNPAUSED)) {
/* not yet unpaused; continue later */ /* not yet unpaused; continue later */
(void) sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) if(ksig)
(void) sigaddset(&rmp->mp_ksigpending, signo); sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
@ -585,8 +585,8 @@ register struct mproc *rmp;
if (sigismember(&rmp->mp_sigpending, i) && if (sigismember(&rmp->mp_sigpending, i) &&
!sigismember(&rmp->mp_sigmask, i)) { !sigismember(&rmp->mp_sigmask, i)) {
ksig = sigismember(&rmp->mp_ksigpending, i); ksig = sigismember(&rmp->mp_ksigpending, i);
(void) sigdelset(&rmp->mp_sigpending, i); sigdelset(&rmp->mp_sigpending, i);
(void) sigdelset(&rmp->mp_ksigpending, i); sigdelset(&rmp->mp_ksigpending, i);
sig_proc(rmp, i, FALSE /*trace*/, ksig); sig_proc(rmp, i, FALSE /*trace*/, ksig);
if (rmp->mp_flags & VFS_CALL) if (rmp->mp_flags & VFS_CALL)
@ -722,16 +722,16 @@ int signo; /* signal to send to process (1 to _NSIG-1) */
rmp->mp_sigmask |= rmp->mp_sigact[signo].sa_mask; rmp->mp_sigmask |= rmp->mp_sigact[signo].sa_mask;
if (sigflags & SA_NODEFER) if (sigflags & SA_NODEFER)
(void) sigdelset(&rmp->mp_sigmask, signo); sigdelset(&rmp->mp_sigmask, signo);
else else
(void) sigaddset(&rmp->mp_sigmask, signo); sigaddset(&rmp->mp_sigmask, signo);
if (sigflags & SA_RESETHAND) { if (sigflags & SA_RESETHAND) {
(void) sigdelset(&rmp->mp_catch, signo); sigdelset(&rmp->mp_catch, signo);
rmp->mp_sigact[signo].sa_handler = SIG_DFL; rmp->mp_sigact[signo].sa_handler = SIG_DFL;
} }
(void) sigdelset(&rmp->mp_sigpending, signo); sigdelset(&rmp->mp_sigpending, signo);
(void) sigdelset(&rmp->mp_ksigpending, signo); sigdelset(&rmp->mp_ksigpending, signo);
if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK) if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK)
return(FALSE); return(FALSE);

View File

@ -213,7 +213,7 @@ PUBLIC int do_trace()
/* Let all tracer-pending signals through the filter. */ /* Let all tracer-pending signals through the filter. */
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember(&child->mp_sigtrace, i)) { if (sigismember(&child->mp_sigtrace, i)) {
(void) sigdelset(&child->mp_sigtrace, i); sigdelset(&child->mp_sigtrace, i);
check_sig(child->mp_pid, i, FALSE /* ksig */); check_sig(child->mp_pid, i, FALSE /* ksig */);
} }
} }
@ -281,7 +281,7 @@ int signo;
rmp->mp_flags |= STOPPED; rmp->mp_flags |= STOPPED;
if (wait_test(rpmp, rmp)) { if (wait_test(rpmp, rmp)) {
(void) sigdelset(&rmp->mp_sigtrace, signo); sigdelset(&rmp->mp_sigtrace, signo);
rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */ rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */
rpmp->mp_reply.reply_res2 = 0177 | (signo << 8); rpmp->mp_reply.reply_res2 = 0177 | (signo << 8);