aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2018-11-28 18:12:30 +0100
committerNick Mathewson <nickm@torproject.org>2018-12-17 16:39:28 -0500
commit22cb3c6ce9164920ff81013d5f8dce3c26911af4 (patch)
tree7959598dea4a1e50f64a40082f0820071b9d063e
parentbc6983afed24c0b83a49d2cef531dcc036245a04 (diff)
downloadtor-22cb3c6ce9164920ff81013d5f8dce3c26911af4.tar.gz
tor-22cb3c6ce9164920ff81013d5f8dce3c26911af4.zip
Call close() on stdin/stdout/stderr in process_terminate().
Call close() on all process handles after we have called kill(pid, SIGTERM). See: https://bugs.torproject.org/28179
-rw-r--r--src/lib/process/process_unix.c59
-rw-r--r--src/lib/process/process_unix.h1
-rw-r--r--src/lib/process/process_win32.c5
3 files changed, 62 insertions, 3 deletions
diff --git a/src/lib/process/process_unix.c b/src/lib/process/process_unix.c
index 4a9aaa2edd..04d6381aa3 100644
--- a/src/lib/process/process_unix.c
+++ b/src/lib/process/process_unix.c
@@ -119,7 +119,11 @@ process_unix_free_(process_unix_t *unix_process)
if (! unix_process->stderr_handle.reached_eof)
process_unix_stop_reading(&unix_process->stderr_handle);
- process_unix_stop_writing(&unix_process->stdin_handle);
+ if (unix_process->stdin_handle.is_writing)
+ process_unix_stop_writing(&unix_process->stdin_handle);
+
+ /* Close all our file descriptors. */
+ process_unix_close_file_descriptors(unix_process);
tor_event_free(unix_process->stdout_handle.event);
tor_event_free(unix_process->stderr_handle.event);
@@ -368,6 +372,8 @@ process_unix_terminate(process_t *process)
if (BUG(unix_process->waitpid == NULL))
return false;
+ bool success = true;
+
/* Send a SIGTERM to our child process. */
int ret;
@@ -376,10 +382,14 @@ process_unix_terminate(process_t *process)
if (ret == -1) {
log_warn(LD_PROCESS, "Unable to terminate process: %s",
strerror(errno));
- return false;
+ success = false;
}
- return ret == 0;
+ /* Close all our FD's. */
+ if (! process_unix_close_file_descriptors(unix_process))
+ success = false;
+
+ return success;
}
/** Returns the unique process identifier for the given <b>process</b>. */
@@ -648,4 +658,47 @@ process_unix_read_handle(process_t *process,
return ret;
}
+/** Close the standard in, out, and error handles of the given
+ * <b>unix_process</b>. */
+STATIC bool
+process_unix_close_file_descriptors(process_unix_t *unix_process)
+{
+ tor_assert(unix_process);
+
+ int ret;
+ bool success = true;
+
+ if (unix_process->stdin_handle.fd != -1) {
+ ret = close(unix_process->stdin_handle.fd);
+ if (ret == -1) {
+ log_warn(LD_PROCESS, "Unable to close standard in");
+ success = false;
+ }
+
+ unix_process->stdin_handle.fd = -1;
+ }
+
+ if (unix_process->stdout_handle.fd != -1) {
+ ret = close(unix_process->stdout_handle.fd);
+ if (ret == -1) {
+ log_warn(LD_PROCESS, "Unable to close standard out");
+ success = false;
+ }
+
+ unix_process->stdout_handle.fd = -1;
+ }
+
+ if (unix_process->stderr_handle.fd != -1) {
+ ret = close(unix_process->stderr_handle.fd);
+ if (ret == -1) {
+ log_warn(LD_PROCESS, "Unable to close standard error");
+ success = false;
+ }
+
+ unix_process->stderr_handle.fd = -1;
+ }
+
+ return success;
+}
+
#endif /* defined(_WIN32). */
diff --git a/src/lib/process/process_unix.h b/src/lib/process/process_unix.h
index e17c59ea81..86c10d7449 100644
--- a/src/lib/process/process_unix.h
+++ b/src/lib/process/process_unix.h
@@ -60,6 +60,7 @@ STATIC void process_unix_setup_handle(process_t *process,
STATIC int process_unix_read_handle(process_t *,
process_unix_handle_t *,
buf_t *);
+STATIC bool process_unix_close_file_descriptors(process_unix_t *);
#endif /* defined(PROCESS_UNIX_PRIVATE). */
#endif /* defined(_WIN32). */
diff --git a/src/lib/process/process_win32.c b/src/lib/process/process_win32.c
index 73e19d518f..e75328f3e8 100644
--- a/src/lib/process/process_win32.c
+++ b/src/lib/process/process_win32.c
@@ -293,6 +293,11 @@ process_win32_terminate(process_t *process)
return false;
}
+ /* Cleanup our handles. */
+ process_win32_cleanup_handle(&win32_process->stdin_handle);
+ process_win32_cleanup_handle(&win32_process->stdout_handle);
+ process_win32_cleanup_handle(&win32_process->stderr_handle);
+
return true;
}