[tor-commits] [tor/master] Add a 'NoExec' option that causes tor_spawn_background() to fail

nickm at torproject.org nickm at torproject.org
Thu Aug 24 13:23:53 UTC 2017


commit eb43401bfb6d69db66d256582a99e63de7d222d8
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Aug 9 10:42:37 2017 -0400

    Add a 'NoExec' option that causes tor_spawn_background() to fail
    
    Core of an implementation for 22976.
---
 changes/feature22976 |  7 +++++++
 doc/tor.1.txt        |  7 +++++++
 src/common/util.c    | 17 +++++++++++++++++
 src/common/util.h    |  2 ++
 src/or/config.c      | 11 +++++++++++
 src/or/or.h          |  4 ++++
 6 files changed, 48 insertions(+)

diff --git a/changes/feature22976 b/changes/feature22976
new file mode 100644
index 000000000..334f47ad0
--- /dev/null
+++ b/changes/feature22976
@@ -0,0 +1,7 @@
+  o Minor features (integration, hardening):
+    - Added a new NoExec option to . When this option is set to 1,
+      Tor will never try to run another program, regardless of
+      the settings of PortForwardingHelper, ClientTransportPlugin,
+      or ServerTransportPlugin. Once NoExec is set, it cannot be
+      disabled without restarting Tor.
+      Closes ticket 22976.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index b4a3cc5f7..fb19ce38b 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -773,6 +773,13 @@ GENERAL OPTIONS
     circuits.  If the option is set to "default", we obey a
     parameter in the consensus document. (Default: auto)
 
+[[NoExec]] **NoExec** **0**|**1**::
+    If this option is set to 1, then Tor will never launch another
+    executable, regardless of the settings of PortForwardingHelper,
+    ClientTransportPlugin, or ServerTransportPlugin.  Once this
+    option has been set to 1, it cannot be set back to 0 without
+    restarting Tor. (Default: 0)
+
 CLIENT OPTIONS
 --------------
 
diff --git a/src/common/util.c b/src/common/util.c
index 0858d17fe..18108fc24 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -4142,6 +4142,20 @@ process_handle_waitpid_cb(int status, void *arg)
 #define CHILD_STATE_EXEC 8
 #define CHILD_STATE_FAILEXEC 9
 /** @} */
+/**
+ * Boolean.  If true, then Tor may call execve or CreateProcess via
+ * tor_spawn_background.
+ **/
+static int may_spawn_background_process = 1;
+/**
+ * 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;
+}
 /** Start a program in the background. If <b>filename</b> contains a '/', then
  * it will be treated as an absolute or relative path.  Otherwise, on
  * non-Windows systems, the system path will be searched for <b>filename</b>.
@@ -4166,6 +4180,9 @@ tor_spawn_background(const char *const filename, const char **argv,
                      process_environment_t *env,
                      process_handle_t **process_handle_out)
 {
+  if (may_spawn_background_process == 0)
+    return PROCESS_STATUS_ERROR;
+
 #ifdef _WIN32
   HANDLE stdout_pipe_read = NULL;
   HANDLE stdout_pipe_write = NULL;
diff --git a/src/common/util.h b/src/common/util.h
index df581d240..f50cf043a 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -396,6 +396,8 @@ void tor_check_port_forwarding(const char *filename,
                                struct smartlist_t *ports_to_forward,
                                time_t now);
 
+void tor_disable_spawning_background_processes(void);
+
 typedef struct process_handle_t process_handle_t;
 typedef struct process_environment_t process_environment_t;
 int tor_spawn_background(const char *const filename, const char **argv,
diff --git a/src/or/config.c b/src/or/config.c
index 9b6bf40eb..16e4ded69 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -409,6 +409,7 @@ static config_var_t option_vars_[] = {
   OBSOLETE("PredictedPortsRelevanceTime"),
   OBSOLETE("WarnUnsafeSocks"),
   VAR("NodeFamily",              LINELIST, NodeFamilies,         NULL),
+  V(NoExec,                      BOOL,     "0"),
   V(NumCPUs,                     UINT,     "0"),
   V(NumDirectoryGuards,          UINT,     "0"),
   V(NumEntryGuards,              UINT,     "0"),
@@ -1595,6 +1596,10 @@ options_act(const or_options_t *old_options)
   const int transition_affects_guards =
     old_options && options_transition_affects_guards(old_options, options);
 
+  if (options->NoExec) {
+    tor_disable_spawning_background_processes();
+  }
+
   /* disable ptrace and later, other basic debugging techniques */
   {
     /* Remember if we already disabled debugger attachment */
@@ -4447,6 +4452,12 @@ options_transition_allowed(const or_options_t *old,
     return -1;
   }
 
+  if (old->NoExec && !new_val->NoExec) {
+    *msg = tor_strdup("While Tor is running, disabling "
+                      "NoExec is not allowed.");
+    return -1;
+  }
+
   if (sandbox_is_active()) {
 #define SB_NOCHANGE_STR(opt)                                            \
     do {                                                                \
diff --git a/src/or/or.h b/src/or/or.h
index ff11c7279..e24bfd7cd 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -4596,6 +4596,10 @@ typedef struct {
    * consensuses around so that we can generate diffs from them.  If 0,
    * use the default. */
   int MaxConsensusAgeForDiffs;
+
+  /** Bool (default: 0). Tells Tor to never try to exec another program.
+   */
+  int NoExec;
 } or_options_t;
 
 /** Persistent state for an onion router, as saved to disk. */





More information about the tor-commits mailing list