Don't allow sending invalid signals from user space

Don't allow signal 0 in signal(2), sigaction(2), siginterrupt(3).
Don't allow any signal in sigqueue(3) but explicitely handle
signal 0 as in kill(2).

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-11-24 14:10:41 +01:00
parent e1913d218d
commit f993cb708b
1 changed files with 22 additions and 12 deletions

View File

@ -34,7 +34,7 @@ signal (int sig, _sig_func_ptr func)
_sig_func_ptr prev; _sig_func_ptr prev;
/* check that sig is in right range */ /* check that sig is in right range */
if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
{ {
set_errno (EINVAL); set_errno (EINVAL);
syscall_printf ("SIG_ERR = signal (%d, %p)", sig, func); syscall_printf ("SIG_ERR = signal (%d, %p)", sig, func);
@ -387,7 +387,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
{ {
sig_dispatch_pending (); sig_dispatch_pending ();
/* check that sig is in right range */ /* check that sig is in right range */
if (sig < 0 || sig >= NSIG) if (sig <= 0 || sig >= NSIG)
set_errno (EINVAL); set_errno (EINVAL);
else else
{ {
@ -535,18 +535,21 @@ extern "C" int
siginterrupt (int sig, int flag) siginterrupt (int sig, int flag)
{ {
struct sigaction act; struct sigaction act;
sigaction (sig, NULL, &act); int res = sigaction_worker (sig, NULL, &act, false);
if (flag) if (res == 0)
{ {
act.sa_flags &= ~SA_RESTART; if (flag)
act.sa_flags |= _SA_NORESTART; {
act.sa_flags &= ~SA_RESTART;
act.sa_flags |= _SA_NORESTART;
}
else
{
act.sa_flags &= ~_SA_NORESTART;
act.sa_flags |= SA_RESTART;
}
res = sigaction_worker (sig, &act, NULL, true);
} }
else
{
act.sa_flags &= ~_SA_NORESTART;
act.sa_flags |= SA_RESTART;
}
int res = sigaction_worker (sig, &act, NULL, true);
syscall_printf ("%R = siginterrupt(%d, %y)", sig, flag); syscall_printf ("%R = siginterrupt(%d, %y)", sig, flag);
return res; return res;
} }
@ -622,6 +625,13 @@ sigqueue (pid_t pid, int sig, const union sigval value)
set_errno (ESRCH); set_errno (ESRCH);
return -1; return -1;
} }
if (sig == 0)
return 0;
if (sig < 0 || sig >= NSIG)
{
set_errno (EINVAL);
return -1;
}
si.si_signo = sig; si.si_signo = sig;
si.si_code = SI_QUEUE; si.si_code = SI_QUEUE;
si.si_value = value; si.si_value = value;