rc: block SIGCHLD during pid list operations
the pid list will be accessed inside the SIGCHLD signal handler. so we must ensure SIGCHLD handler doesn't get invoked while the list is at an inconsistent state making it unsafe to interact with. Co-authored-by: Dominique MARTINET <dominique.martinet@atmark-techno.com> Bug: https://github.com/OpenRC/openrc/issues/589#issuecomment-1406588576
This commit is contained in:
parent
bbd3acfc67
commit
0b4732520f
@ -351,16 +351,31 @@ static char *get_krunlevel(void)
|
|||||||
static void
|
static void
|
||||||
add_pid(pid_t pid)
|
add_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
|
sigset_t sset, old;
|
||||||
RC_PID *p = xmalloc(sizeof(*p));
|
RC_PID *p = xmalloc(sizeof(*p));
|
||||||
p->pid = pid;
|
p->pid = pid;
|
||||||
|
|
||||||
|
/* this list will be accessed inside the SIGCHLD signal handler.
|
||||||
|
* so we need to ensure that the SIGCHLD handler doesn't get invoked
|
||||||
|
* while the list is at an inconsistent state.
|
||||||
|
*/
|
||||||
|
sigemptyset(&sset);
|
||||||
|
sigaddset(&sset, SIGCHLD);
|
||||||
|
sigprocmask(SIG_SETMASK, &sset, &old);
|
||||||
LIST_INSERT_HEAD(&service_pids, p, entries);
|
LIST_INSERT_HEAD(&service_pids, p, entries);
|
||||||
|
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_pid(pid_t pid, bool inside_signal)
|
remove_pid(pid_t pid, bool inside_signal)
|
||||||
{
|
{
|
||||||
|
sigset_t sset, old;
|
||||||
RC_PID *p, *tmp;
|
RC_PID *p, *tmp;
|
||||||
|
|
||||||
|
/* same rationale for blocking SIGCHLD as add_pid() */
|
||||||
|
sigemptyset(&sset);
|
||||||
|
sigaddset(&sset, SIGCHLD);
|
||||||
|
sigprocmask(SIG_SETMASK, &sset, &old);
|
||||||
LIST_FOREACH(p, &service_pids, entries) {
|
LIST_FOREACH(p, &service_pids, entries) {
|
||||||
if (p->pid == pid) {
|
if (p->pid == pid) {
|
||||||
LIST_REMOVE(p, entries);
|
LIST_REMOVE(p, entries);
|
||||||
@ -375,6 +390,7 @@ remove_pid(pid_t pid, bool inside_signal)
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sigprocmask(SIG_SETMASK, &old, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user