Commit ca0279be authored by Paul Eggert's avatar Paul Eggert
Browse files

Don't kill already-reaped process.

* process.c (process_send_signal): Fix race condition where a
subprocess was reaped by a signal handler between the check for
liveness and calling 'kill', which meant that Emacs could in
theory kill an innocent bystander process.  Do the fix by blocking
SIGCHLD in a critical section that checks liveness before killing.

Fixes: debbugs:17561
parent 9aecbeb3
2014-05-27 Paul Eggert <eggert@cs.ucla.edu>
Don't kill already-reaped process (Bug#17561).
* process.c (process_send_signal): Fix race condition where a
subprocess was reaped by a signal handler between the check for
liveness and calling 'kill', which meant that Emacs could in
theory kill an innocent bystander process. Do the fix by blocking
SIGCHLD in a critical section that checks liveness before killing.
2014-05-26 Eli Zaretskii <eliz@gnu.org> 2014-05-26 Eli Zaretskii <eliz@gnu.org>
* w32.c (_ANONYMOUS_UNION, _ANONYMOUS_STRUCT): Define only if * w32.c (_ANONYMOUS_UNION, _ANONYMOUS_STRUCT): Define only if
......
...@@ -5833,30 +5833,25 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, ...@@ -5833,30 +5833,25 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
} }
#endif #endif
#ifdef TIOCSIGSEND
/* Work around a HP-UX 7.0 bug that mishandles signals to subjobs.
We don't know whether the bug is fixed in later HP-UX versions. */
if (! NILP (current_group) && ioctl (p->infd, TIOCSIGSEND, signo) != -1)
return;
#endif
/* If we don't have process groups, send the signal to the immediate /* If we don't have process groups, send the signal to the immediate
subprocess. That isn't really right, but it's better than any subprocess. That isn't really right, but it's better than any
obvious alternative. */ obvious alternative. */
if (no_pgrp) pid_t pid = no_pgrp ? gid : - gid;
{
kill (p->pid, signo);
return;
}
/* gid may be a pid, or minus a pgrp's number */ /* Do not kill an already-reaped process, as that could kill an
#ifdef TIOCSIGSEND innocent bystander that happens to have the same process ID. */
if (!NILP (current_group)) sigset_t oldset;
{ block_child_signal (&oldset);
if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) if (p->alive)
kill (-gid, signo); kill (pid, signo);
} unblock_child_signal (&oldset);
else
{
gid = - p->pid;
kill (gid, signo);
}
#else /* ! defined (TIOCSIGSEND) */
kill (-gid, signo);
#endif /* ! defined (TIOCSIGSEND) */
} }
DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment