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);
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);
}
@ -425,14 +425,14 @@ int sig_nr; /* signal to be sent */
panic("cause_sig: sig manager %d gets lethal signal %d for itself",
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);
return;
}
/* Check if the signal is already pending. Process it otherwise. */
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 */
RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING);
send_sig(sig_mgr, SIGKSIG);

View file

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

View file

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

View file

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

View file

@ -213,7 +213,7 @@ PUBLIC int do_trace()
/* Let all tracer-pending signals through the filter. */
for (i = 1; i < _NSIG; 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 */);
}
}
@ -281,7 +281,7 @@ int signo;
rmp->mp_flags |= STOPPED;
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_reply.reply_res2 = 0177 | (signo << 8);