diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2016-11-24 16:10:41 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-11-24 16:24:07 +0300 |
commit | f993cb708b6e779325f06c706e6a10f2b2ffbf25 (patch) | |
tree | 83ace540b0894f43c089ec5e0f0947bf34060e41 | |
parent | e1913d218d8037e7e7a733f40c8cd6f6891916b5 (diff) |
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>
-rw-r--r-- | winsup/cygwin/signal.cc | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 3d5049ee2..f371a231b 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -34,7 +34,7 @@ signal (int sig, _sig_func_ptr func) _sig_func_ptr prev; /* 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); syscall_printf ("SIG_ERR = signal (%d, %p)", sig, func); @@ -387,7 +387,7 @@ sigaction_worker (int sig, const struct sigaction *newact, { sig_dispatch_pending (); /* check that sig is in right range */ - if (sig < 0 || sig >= NSIG) + if (sig <= 0 || sig >= NSIG) set_errno (EINVAL); else { @@ -535,18 +535,21 @@ extern "C" int siginterrupt (int sig, int flag) { struct sigaction act; - sigaction (sig, NULL, &act); - if (flag) + int res = sigaction_worker (sig, NULL, &act, false); + if (res == 0) { - act.sa_flags &= ~SA_RESTART; - act.sa_flags |= _SA_NORESTART; - } - else - { - act.sa_flags &= ~_SA_NORESTART; - act.sa_flags |= SA_RESTART; + if (flag) + { + 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); } - int res = sigaction_worker (sig, &act, NULL, true); syscall_printf ("%R = siginterrupt(%d, %y)", sig, flag); return res; } @@ -622,6 +625,13 @@ sigqueue (pid_t pid, int sig, const union sigval value) set_errno (ESRCH); return -1; } + if (sig == 0) + return 0; + if (sig < 0 || sig >= NSIG) + { + set_errno (EINVAL); + return -1; + } si.si_signo = sig; si.si_code = SI_QUEUE; si.si_value = value; |