diff options
author | Alexander Færøy <ahf@torproject.org> | 2018-11-28 18:12:30 +0100 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-12-17 16:39:28 -0500 |
commit | 22cb3c6ce9164920ff81013d5f8dce3c26911af4 (patch) | |
tree | 7959598dea4a1e50f64a40082f0820071b9d063e | |
parent | bc6983afed24c0b83a49d2cef531dcc036245a04 (diff) | |
download | tor-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.c | 59 | ||||
-rw-r--r-- | src/lib/process/process_unix.h | 1 | ||||
-rw-r--r-- | src/lib/process/process_win32.c | 5 |
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; } |