mirror of
https://git.musl-libc.org/git/musl
synced 2025-01-23 06:32:05 +03:00
fix race condition in raise - just mask signals
a signal handler could fork after the pid/tid were read, causing the wrong process to be signalled. i'm not sure if this is supposed to have UB or not, but raise is async-signal-safe, so it probably is allowed. the current solution is slightly expensive so this implementation is likely to be changed in the future.
This commit is contained in:
parent
370f78f2c8
commit
0bed7e0acf
@ -2,17 +2,17 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
|
||||||
|
int __sigprocmask(int, const sigset_t *, sigset_t *);
|
||||||
|
|
||||||
int raise(int sig)
|
int raise(int sig)
|
||||||
{
|
{
|
||||||
int pid, tid, ret;
|
int pid, tid, ret;
|
||||||
/* Getting the pid/tid pair is not atomic, and could give wrong
|
sigset_t set;
|
||||||
* result if a fork occurs in a signal handler between the two
|
sigfillset(&set);
|
||||||
* syscalls. Use the tgkill syscall's ESRCH semantics to detect
|
__sigprocmask(SIG_BLOCK, &set, &set);
|
||||||
* this condition and retry. */
|
tid = syscall0(__NR_gettid);
|
||||||
do {
|
pid = syscall0(__NR_getpid);
|
||||||
tid = syscall0(__NR_gettid);
|
ret = syscall3(__NR_tgkill, pid, tid, sig);
|
||||||
pid = syscall0(__NR_getpid);
|
__sigprocmask(SIG_SETMASK, &set, 0);
|
||||||
ret = syscall3(__NR_tgkill, pid, tid, sig);
|
|
||||||
} while (ret<0 && errno == ESRCH);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user