mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-08 18:19:08 +08:00
Cygwin: sigtimedwait: Fix segfault when timeout is used
Previously, two bugs exist in sigtimedwait(). One is, that since _my_tls.sigwait_mask was left non-zero if the signal arrives after the timeout, sigpacket::process() would wrongly try to handle it. The other is if a timeout occurs after sigpacket::process() is called, but not completed yet, the signal handler can be called accidentally. If the signal handler is set to SIG_DFL or SIG_IGN, access violation will occur in both cases. With this patch, in sigwait_common(), check if sigwait_mask == 0 to confirm that sigpacket::process() cleared it. In this case, do not treat WAIT_TIMEOUT, but call cygwait() again to retrieve the signal. Furthermore, sigpacket::process() checks whether timeout occurs in sigwait_common() and if timeout already happens, do not treat the signal as waited. In both cases, to avoid race issues, the code is guarded by cygtls::lock(). Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256762.html Fixes: 24ff42d79aab ("Cygwin: Implement sigtimedwait") Reported-by: Christian Franke <Christian.Franke@t-online.de> Reviewed-by: Corinna Vinschen <corinna@vinschen.de> Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp> (cherry picked from commit 26144e4008cd8f7288f3387eea697bba4006e16f)
This commit is contained in:
parent
2196f93fda
commit
46474ecf57
@ -1527,11 +1527,14 @@ sigpacket::process ()
|
|||||||
if ((HANDLE) *tls)
|
if ((HANDLE) *tls)
|
||||||
tls->signal_debugger (si);
|
tls->signal_debugger (si);
|
||||||
|
|
||||||
if (issig_wait)
|
tls->lock ();
|
||||||
|
if (issig_wait && tls->sigwait_mask != 0)
|
||||||
{
|
{
|
||||||
tls->sigwait_mask = 0;
|
tls->sigwait_mask = 0;
|
||||||
|
tls->unlock ();
|
||||||
goto dosig;
|
goto dosig;
|
||||||
}
|
}
|
||||||
|
tls->unlock ();
|
||||||
|
|
||||||
if (handler == SIG_IGN)
|
if (handler == SIG_IGN)
|
||||||
{
|
{
|
||||||
|
@ -42,3 +42,6 @@ Fixes:
|
|||||||
|
|
||||||
- Fix NtCreateEvent() error in create_lock_ob() called from flock().
|
- Fix NtCreateEvent() error in create_lock_ob() called from flock().
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256750.html
|
Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256750.html
|
||||||
|
|
||||||
|
- Fix segfault in sigtimedwait() when using timeout.
|
||||||
|
Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256762.html
|
||||||
|
@ -615,6 +615,7 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime)
|
|||||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||||
sig_dispatch_pending (true);
|
sig_dispatch_pending (true);
|
||||||
|
|
||||||
|
do_wait:
|
||||||
switch (cygwait (NULL, waittime,
|
switch (cygwait (NULL, waittime,
|
||||||
cw_sig_eintr | cw_cancel | cw_cancel_self))
|
cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||||
{
|
{
|
||||||
@ -640,6 +641,17 @@ sigwait_common (const sigset_t *set, siginfo_t *info, PLARGE_INTEGER waittime)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
|
_my_tls.lock ();
|
||||||
|
if (_my_tls.sigwait_mask == 0)
|
||||||
|
{
|
||||||
|
/* sigpacket::process() already started.
|
||||||
|
Will surely be signalled soon. */
|
||||||
|
waittime = cw_infinite;
|
||||||
|
_my_tls.unlock ();
|
||||||
|
goto do_wait;
|
||||||
|
}
|
||||||
|
_my_tls.sigwait_mask = 0;
|
||||||
|
_my_tls.unlock ();
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user