diff --git a/src/app/config/config.c b/src/app/config/config.c
index 90eae50fdd..e33c6b26e8 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -142,7 +142,7 @@
#include "lib/process/pidfile.h"
#include "lib/process/restrict.h"
#include "lib/process/setuid.h"
-#include "lib/process/subprocess.h"
+#include "lib/process/process.h"
#include "lib/net/gethostname.h"
#include "lib/thread/numcpus.h"
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c
index fd4bec7807..0e326f90e9 100644
--- a/src/feature/client/transports.c
+++ b/src/feature/client/transports.c
@@ -103,7 +103,6 @@
#include "feature/control/control.h"
#include "lib/process/process.h"
-#include "lib/process/subprocess.h"
#include "lib/process/env.h"
static smartlist_t *
diff --git a/src/lib/process/include.am b/src/lib/process/include.am
index aa73356146..a2d54b6238 100644
--- a/src/lib/process/include.am
+++ b/src/lib/process/include.am
@@ -14,7 +14,6 @@ src_lib_libtor_process_a_SOURCES = \
src/lib/process/process_win32.c \
src/lib/process/restrict.c \
src/lib/process/setuid.c \
- src/lib/process/subprocess.c \
src/lib/process/waitpid.c \
src/lib/process/winprocess_sys.c
@@ -32,6 +31,5 @@ noinst_HEADERS += \
src/lib/process/process_win32.h \
src/lib/process/restrict.h \
src/lib/process/setuid.h \
- src/lib/process/subprocess.h \
src/lib/process/waitpid.h \
src/lib/process/winprocess_sys.h
diff --git a/src/lib/process/process.c b/src/lib/process/process.c
index 915217e132..7275d0a21b 100644
--- a/src/lib/process/process.c
+++ b/src/lib/process/process.c
@@ -26,6 +26,12 @@
/** A list of all process_t instances currently allocated. */
static smartlist_t *processes;
+/**
+ * Boolean. If true, then Tor may call execve or CreateProcess via
+ * tor_spawn_background.
+ **/
+static int may_spawn_background_process = 1;
+
/** Structure to represent a child process. */
struct process_t {
/** Process status. */
@@ -114,6 +120,16 @@ process_protocol_to_string(process_protocol_t protocol)
/* LCOV_EXCL_STOP */
}
+/**
+ * Turn off may_spawn_background_process, so that all future calls to
+ * tor_spawn_background are guaranteed to fail.
+ **/
+void
+tor_disable_spawning_background_processes(void)
+{
+ may_spawn_background_process = 0;
+}
+
/** Initialize the Process subsystem. This function initializes the Process
* subsystem's global state. For cleaning up, process_free_all() should
* be called. */
@@ -234,6 +250,9 @@ process_exec(process_t *process)
{
tor_assert(process);
+ if (BUG(may_spawn_background_process == 0))
+ return PROCESS_STATUS_ERROR;
+
process_status_t status = PROCESS_STATUS_NOT_RUNNING;
log_info(LD_PROCESS, "Starting new process: %s", process->command);
diff --git a/src/lib/process/process.h b/src/lib/process/process.h
index 6092c2da7d..cb5bccbf7b 100644
--- a/src/lib/process/process.h
+++ b/src/lib/process/process.h
@@ -45,6 +45,8 @@ typedef enum {
const char *process_protocol_to_string(process_protocol_t protocol);
+void tor_disable_spawning_background_processes(void);
+
struct process_t;
typedef struct process_t process_t;
diff --git a/src/lib/process/process_win32.c b/src/lib/process/process_win32.c
index 7b18903c70..73e19d518f 100644
--- a/src/lib/process/process_win32.c
+++ b/src/lib/process/process_win32.c
@@ -18,13 +18,16 @@
#include "lib/log/win32err.h"
#include "lib/process/process.h"
#include "lib/process/process_win32.h"
-#include "lib/process/subprocess.h"
#include "lib/process/env.h"
#ifdef HAVE_SYS_TIME_H
#include
#endif
+#ifdef HAVE_STRING_H
+#include
+#endif
+
#ifdef _WIN32
/** The size of our intermediate buffers. */
@@ -889,4 +892,104 @@ process_win32_handle_read_completion(process_win32_handle_t *handle,
return false;
}
+/** Format a single argument for being put on a Windows command line.
+ * Returns a newly allocated string */
+STATIC char *
+format_win_cmdline_argument(const char *arg)
+{
+ char *formatted_arg;
+ char need_quotes;
+ const char *c;
+ int i;
+ int bs_counter = 0;
+ /* Backslash we can point to when one is inserted into the string */
+ const char backslash = '\\';
+
+ /* Smartlist of *char */
+ smartlist_t *arg_chars;
+ arg_chars = smartlist_new();
+
+ /* Quote string if it contains whitespace or is empty */
+ need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
+
+ /* Build up smartlist of *chars */
+ for (c=arg; *c != '\0'; c++) {
+ if ('"' == *c) {
+ /* Double up backslashes preceding a quote */
+ for (i=0; i<(bs_counter*2); i++)
+ smartlist_add(arg_chars, (void*)&backslash);
+ bs_counter = 0;
+ /* Escape the quote */
+ smartlist_add(arg_chars, (void*)&backslash);
+ smartlist_add(arg_chars, (void*)c);
+ } else if ('\\' == *c) {
+ /* Count backslashes until we know whether to double up */
+ bs_counter++;
+ } else {
+ /* Don't double up slashes preceding a non-quote */
+ for (i=0; i
-#endif
-#ifdef HAVE_SYS_PRCTL_H
-#include
-#endif
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-#ifdef HAVE_SIGNAL_H
-#include
-#endif
-#ifdef HAVE_FCNTL_H
-#include
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include
-#endif
-#include
-#include
-
-/** Format a single argument for being put on a Windows command line.
- * Returns a newly allocated string */
-static char *
-format_win_cmdline_argument(const char *arg)
-{
- char *formatted_arg;
- char need_quotes;
- const char *c;
- int i;
- int bs_counter = 0;
- /* Backslash we can point to when one is inserted into the string */
- const char backslash = '\\';
-
- /* Smartlist of *char */
- smartlist_t *arg_chars;
- arg_chars = smartlist_new();
-
- /* Quote string if it contains whitespace or is empty */
- need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
-
- /* Build up smartlist of *chars */
- for (c=arg; *c != '\0'; c++) {
- if ('"' == *c) {
- /* Double up backslashes preceding a quote */
- for (i=0; i<(bs_counter*2); i++)
- smartlist_add(arg_chars, (void*)&backslash);
- bs_counter = 0;
- /* Escape the quote */
- smartlist_add(arg_chars, (void*)&backslash);
- smartlist_add(arg_chars, (void*)c);
- } else if ('\\' == *c) {
- /* Count backslashes until we know whether to double up */
- bs_counter++;
- } else {
- /* Don't double up slashes preceding a non-quote */
- for (i=0; i
diff --git a/src/test/test_process.c b/src/test/test_process.c
index 2fcb3f6686..3640b86688 100644
--- a/src/test/test_process.c
+++ b/src/test/test_process.c
@@ -628,11 +628,51 @@ test_win32(void *arg)
process_init();
process_t *process = process_new("");
+ char *joined_argv = NULL;
/* On Win32 all processes should have a Win32 process handle. */
tt_ptr_op(NULL, OP_NE, process_get_win32_process(process));
+ /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
+ * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
+ * will try to only generate simple cases for the child process to parse;
+ * i.e. we never embed quoted strings in arguments. */
+
+ const char *argvs[][4] = {
+ {"a", "bb", "CCC", NULL}, // Normal
+ {NULL, NULL, NULL, NULL}, // Empty argument list
+ {"", NULL, NULL, NULL}, // Empty argument
+ {"\"a", "b\"b", "CCC\"", NULL}, // Quotes
+ {"a\tbc", "dd dd", "E", NULL}, // Whitespace
+ {"a\\\\\\b", "de fg", "H", NULL}, // Backslashes
+ {"a\\\"b", "\\c", "D\\", NULL}, // Backslashes before quote
+ {"a\\\\b c", "d", "E", NULL}, // Backslashes not before quote
+ { NULL } // Terminator
+ };
+
+ const char *cmdlines[] = {
+ "a bb CCC",
+ "",
+ "\"\"",
+ "\\\"a b\\\"b CCC\\\"",
+ "\"a\tbc\" \"dd dd\" E",
+ "a\\\\\\b \"de fg\" H",
+ "a\\\\\\\"b \\c D\\",
+ "\"a\\\\b c\" d E",
+ NULL // Terminator
+ };
+
+ int i;
+
+ for (i=0; cmdlines[i]!=NULL; i++) {
+ log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
+ joined_argv = tor_join_win_cmdline(argvs[i]);
+ tt_str_op(cmdlines[i],OP_EQ, joined_argv);
+ tor_free(joined_argv);
+ }
+
done:
+ tor_free(joined_argv);
process_free(process);
process_free_all();
#endif
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index c980276b14..b5572ef80c 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -8,7 +8,6 @@
#define UTIL_PRIVATE
#define STATEFILE_PRIVATE
#define CONTROL_PRIVATE
-#define SUBPROCESS_PRIVATE
#define PROCESS_PRIVATE
#include "core/or/or.h"
#include "app/config/config.h"
@@ -18,7 +17,6 @@
#include "core/or/circuitbuild.h"
#include "app/config/statefile.h"
#include "test/test.h"
-#include "lib/process/subprocess.h"
#include "lib/encoding/confline.h"
#include "lib/net/resolve.h"
#include "lib/process/process.h"
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 4fa67b6419..a94153f2dc 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -10,7 +10,7 @@
#define UTIL_PRIVATE
#define UTIL_MALLOC_PRIVATE
#define SOCKET_PRIVATE
-#define SUBPROCESS_PRIVATE
+#define PROCESS_WIN32_PRIVATE
#include "lib/testsupport/testsupport.h"
#include "core/or/or.h"
#include "lib/container/buffers.h"
@@ -22,6 +22,7 @@
#include "test/test.h"
#include "lib/memarea/memarea.h"
#include "lib/process/waitpid.h"
+#include "lib/process/process_win32.h"
#include "test/log_test_helpers.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_zstd.h"
@@ -30,7 +31,6 @@
#include "lib/fs/winlib.h"
#include "lib/process/env.h"
#include "lib/process/pidfile.h"
-#include "lib/process/subprocess.h"
#include "lib/intmath/weakrng.h"
#include "lib/thread/numcpus.h"
#include "lib/math/fp.h"
@@ -4395,57 +4395,6 @@ test_util_format_dec_number(void *ptr)
return;
}
-/**
- * Test that we can properly format a Windows command line
- */
-static void
-test_util_join_win_cmdline(void *ptr)
-{
- /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
- * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
- * will try to only generate simple cases for the child process to parse;
- * i.e. we never embed quoted strings in arguments. */
-
- const char *argvs[][4] = {
- {"a", "bb", "CCC", NULL}, // Normal
- {NULL, NULL, NULL, NULL}, // Empty argument list
- {"", NULL, NULL, NULL}, // Empty argument
- {"\"a", "b\"b", "CCC\"", NULL}, // Quotes
- {"a\tbc", "dd dd", "E", NULL}, // Whitespace
- {"a\\\\\\b", "de fg", "H", NULL}, // Backslashes
- {"a\\\"b", "\\c", "D\\", NULL}, // Backslashes before quote
- {"a\\\\b c", "d", "E", NULL}, // Backslashes not before quote
- { NULL } // Terminator
- };
-
- const char *cmdlines[] = {
- "a bb CCC",
- "",
- "\"\"",
- "\\\"a b\\\"b CCC\\\"",
- "\"a\tbc\" \"dd dd\" E",
- "a\\\\\\b \"de fg\" H",
- "a\\\\\\\"b \\c D\\",
- "\"a\\\\b c\" d E",
- NULL // Terminator
- };
-
- int i;
- char *joined_argv = NULL;
-
- (void)ptr;
-
- for (i=0; cmdlines[i]!=NULL; i++) {
- log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
- joined_argv = tor_join_win_cmdline(argvs[i]);
- tt_str_op(cmdlines[i],OP_EQ, joined_argv);
- tor_free(joined_argv);
- }
-
- done:
- tor_free(joined_argv);
-}
-
#define MAX_SPLIT_LINE_COUNT 4
struct split_lines_test_t {
const char *orig_line; // Line to be split (may contain \0's)
@@ -6226,7 +6175,6 @@ struct testcase_t util_tests[] = {
UTIL_TEST_WIN_ONLY(load_win_lib, 0),
UTIL_TEST(format_hex_number, 0),
UTIL_TEST(format_dec_number, 0),
- UTIL_TEST(join_win_cmdline, 0),
UTIL_TEST(n_bits_set, 0),
UTIL_TEST(eat_whitespace, 0),
UTIL_TEST(sl_new_from_text_lines, 0),