Browse Source

Merge branch 'disable_signal_handlers'

Nick Mathewson 6 years ago
parent
commit
edd427a8ba
5 changed files with 47 additions and 39 deletions
  1. 5 0
      changes/ticket24588
  2. 2 0
      src/or/config.c
  3. 34 38
      src/or/main.c
  4. 1 1
      src/or/main.h
  5. 5 0
      src/or/or.h

+ 5 - 0
changes/ticket24588

@@ -0,0 +1,5 @@
+  o Minor features (embedding, mobile):
+    - Applications that want to embed Tor can now tell Tor not to register
+      any of its own POSIX signal handlers, using the __DisableSignalHandlers
+      option. This option is not meant for general use. Closes ticket 24588.
+

+ 2 - 0
src/or/config.c

@@ -572,6 +572,7 @@ static config_var_t option_vars_[] = {
   VAR("__ReloadTorrcOnSIGHUP",   BOOL,  ReloadTorrcOnSIGHUP,      "1"),
   VAR("__AllDirActionsPrivate",  BOOL,  AllDirActionsPrivate,     "0"),
   VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
+  VAR("__DisableSignalHandlers", BOOL,  DisableSignalHandlers,    "0"),
   VAR("__LeaveStreamsUnattached",BOOL,  LeaveStreamsUnattached,   "0"),
   VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword,
       NULL),
@@ -4697,6 +4698,7 @@ options_transition_allowed(const or_options_t *old,
   NO_CHANGE_BOOL(DisableDebuggerAttachment);
   NO_CHANGE_BOOL(NoExec);
   NO_CHANGE_INT(OwningControllerFD);
+  NO_CHANGE_BOOL(DisableSignalHandlers);
 
   if (sandbox_is_active()) {
 #define SB_NOCHANGE_STR(opt)                      \

+ 34 - 38
src/or/main.c

@@ -2610,7 +2610,7 @@ do_main_loop(void)
     }
   }
 
-  handle_signals(1);
+  handle_signals();
   monotime_init();
   timers_initialize();
 
@@ -3143,9 +3143,15 @@ exit_function(void)
 #else
 #define UNIX_ONLY 1
 #endif
+
 static struct {
+  /** A numeric code for this signal. Must match the signal value if
+   * try_to_register is true. */
   int signal_value;
+  /** True if we should try to register this signal with libevent and catch
+   * corresponding posix signals. False otherwise. */
   int try_to_register;
+  /** Pointer to hold the event object constructed for this signal. */
   struct event *signal_event;
 } signal_handlers[] = {
 #ifdef SIGINT
@@ -3179,50 +3185,40 @@ static struct {
   { -1, -1, NULL }
 };
 
-/** Set up the signal handlers for either parent or child process */
+/** Set up the signal handler events for this process, and register them
+ * with libevent if appropriate. */
 void
-handle_signals(int is_parent)
+handle_signals(void)
 {
   int i;
-  if (is_parent) {
-    for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
-      if (signal_handlers[i].try_to_register) {
-        signal_handlers[i].signal_event =
-          tor_evsignal_new(tor_libevent_get_base(),
-                           signal_handlers[i].signal_value,
-                           signal_callback,
-                           &signal_handlers[i].signal_value);
-        if (event_add(signal_handlers[i].signal_event, NULL))
-          log_warn(LD_BUG, "Error from libevent when adding "
-                   "event for signal %d",
-                   signal_handlers[i].signal_value);
-      } else {
-        signal_handlers[i].signal_event =
-          tor_event_new(tor_libevent_get_base(), -1,
-                        EV_SIGNAL, signal_callback,
-                        &signal_handlers[i].signal_value);
-      }
+  const int enabled = !get_options()->DisableSignalHandlers;
+
+  for (i = 0; signal_handlers[i].signal_value >= 0; ++i) {
+    /* Signal handlers are only registered with libevent if they need to catch
+     * real POSIX signals.  We construct these signal handler events in either
+     * case, though, so that controllers can activate them with the SIGNAL
+     * command.
+     */
+    if (enabled && signal_handlers[i].try_to_register) {
+      signal_handlers[i].signal_event =
+        tor_evsignal_new(tor_libevent_get_base(),
+                         signal_handlers[i].signal_value,
+                         signal_callback,
+                         &signal_handlers[i].signal_value);
+      if (event_add(signal_handlers[i].signal_event, NULL))
+        log_warn(LD_BUG, "Error from libevent when adding "
+                 "event for signal %d",
+                 signal_handlers[i].signal_value);
+    } else {
+      signal_handlers[i].signal_event =
+        tor_event_new(tor_libevent_get_base(), -1,
+                      EV_SIGNAL, signal_callback,
+                      &signal_handlers[i].signal_value);
     }
-  } else {
-#ifndef _WIN32
-    struct sigaction action;
-    action.sa_flags = 0;
-    sigemptyset(&action.sa_mask);
-    action.sa_handler = SIG_IGN;
-    sigaction(SIGINT,  &action, NULL);
-    sigaction(SIGTERM, &action, NULL);
-    sigaction(SIGPIPE, &action, NULL);
-    sigaction(SIGUSR1, &action, NULL);
-    sigaction(SIGUSR2, &action, NULL);
-    sigaction(SIGHUP,  &action, NULL);
-#ifdef SIGXFSZ
-    sigaction(SIGXFSZ, &action, NULL);
-#endif
-#endif /* !defined(_WIN32) */
   }
 }
 
-/* Make sure the signal handler for signal_num will be called. */
+/* Cause the signal handler for signal_num to be called in the event loop. */
 void
 activate_signal(int signal_num)
 {

+ 1 - 1
src/or/main.h

@@ -66,7 +66,7 @@ MOCK_DECL(long,get_uptime,(void));
 
 unsigned get_signewnym_epoch(void);
 
-void handle_signals(int is_parent);
+void handle_signals(void);
 void activate_signal(int signal_num);
 
 int try_locking(const or_options_t *options, int err_if_locked);

+ 5 - 0
src/or/or.h

@@ -4669,6 +4669,11 @@ typedef struct {
 
   /** List of files that were opened by %include in torrc and torrc-defaults */
   smartlist_t *FilesOpenedByIncludes;
+
+  /** If true, Tor shouldn't install any posix signal handlers, since it is
+   * running embedded inside another process.
+   */
+  int DisableSignalHandlers;
 } or_options_t;
 
 #define LOG_PROTOCOL_WARN (get_protocol_warning_severity_level())