diff options
| author | Paul Eggert | 2014-05-26 20:46:30 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-05-26 20:46:30 -0700 |
| commit | ca0279be7037b3f8bf659ef8b073ea847d0d8553 (patch) | |
| tree | de126355f2188009eee679a4b36b38404838e941 /src/process.c | |
| parent | 9aecbeb30847520f92ba273ec149c9ea5f289c51 (diff) | |
| download | emacs-ca0279be7037b3f8bf659ef8b073ea847d0d8553.tar.gz emacs-ca0279be7037b3f8bf659ef8b073ea847d0d8553.zip | |
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
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/src/process.c b/src/process.c index fdb0501f9ec..561aefc6c9f 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -5833,30 +5833,25 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5833 | } | 5833 | } |
| 5834 | #endif | 5834 | #endif |
| 5835 | 5835 | ||
| 5836 | #ifdef TIOCSIGSEND | ||
| 5837 | /* Work around a HP-UX 7.0 bug that mishandles signals to subjobs. | ||
| 5838 | We don't know whether the bug is fixed in later HP-UX versions. */ | ||
| 5839 | if (! NILP (current_group) && ioctl (p->infd, TIOCSIGSEND, signo) != -1) | ||
| 5840 | return; | ||
| 5841 | #endif | ||
| 5842 | |||
| 5836 | /* If we don't have process groups, send the signal to the immediate | 5843 | /* If we don't have process groups, send the signal to the immediate |
| 5837 | subprocess. That isn't really right, but it's better than any | 5844 | subprocess. That isn't really right, but it's better than any |
| 5838 | obvious alternative. */ | 5845 | obvious alternative. */ |
| 5839 | if (no_pgrp) | 5846 | pid_t pid = no_pgrp ? gid : - gid; |
| 5840 | { | ||
| 5841 | kill (p->pid, signo); | ||
| 5842 | return; | ||
| 5843 | } | ||
| 5844 | 5847 | ||
| 5845 | /* gid may be a pid, or minus a pgrp's number */ | 5848 | /* Do not kill an already-reaped process, as that could kill an |
| 5846 | #ifdef TIOCSIGSEND | 5849 | innocent bystander that happens to have the same process ID. */ |
| 5847 | if (!NILP (current_group)) | 5850 | sigset_t oldset; |
| 5848 | { | 5851 | block_child_signal (&oldset); |
| 5849 | if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) | 5852 | if (p->alive) |
| 5850 | kill (-gid, signo); | 5853 | kill (pid, signo); |
| 5851 | } | 5854 | unblock_child_signal (&oldset); |
| 5852 | else | ||
| 5853 | { | ||
| 5854 | gid = - p->pid; | ||
| 5855 | kill (gid, signo); | ||
| 5856 | } | ||
| 5857 | #else /* ! defined (TIOCSIGSEND) */ | ||
| 5858 | kill (-gid, signo); | ||
| 5859 | #endif /* ! defined (TIOCSIGSEND) */ | ||
| 5860 | } | 5855 | } |
| 5861 | 5856 | ||
| 5862 | DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, | 5857 | DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, |