浏览代码

Merge remote-tracking branch 'ioerror/DisableDebuggerAttachment'

Conflicts:
	src/or/config.c
Nick Mathewson 14 年之前
父节点
当前提交
68114ca52c
共有 4 个文件被更改,包括 87 次插入0 次删除
  1. 14 0
      changes/disable_debugger_attachment
  2. 14 0
      doc/tor.1.txt
  3. 57 0
      src/or/config.c
  4. 2 0
      src/or/or.h

+ 14 - 0
changes/disable_debugger_attachment

@@ -0,0 +1,14 @@
+  o Minor features:
+    - If set to 1, Tor will attempt to prevent basic debugging attachment
+      attempts by other processes. It has no impact for users who wish to
+      attach if they have CAP_SYS_PTRACE or if they are root.  We believe that
+      this feature works on modern Gnu/Linux distributions, and that it may
+      also work on *BSD systems (untested).  Some modern Gnu/Linux systems such
+      as Ubuntu have the kernel.yama.ptrace_scope sysctl and by default enable
+      it as an attempt to limit the PTRACE scope for all user processes by
+      default. This feature will attempt to limit the PTRACE scope for Tor
+      specifically - it will not attempt to alter the system wide ptrace scope
+      as it may not even exist. If you wish to attach to Tor with a debugger
+      such as gdb or strace you will want to set this to 0 for the duration of
+      your debugging. Normal users should leave it on. (Default: 1)
+

+ 14 - 0
doc/tor.1.txt

@@ -258,6 +258,20 @@ Other options can be specified either on the command-line (--option
     option requires that you start your Tor as root, and you should use the
     option requires that you start your Tor as root, and you should use the
     **User** option to properly reduce Tor's privileges. (Default: 0)
     **User** option to properly reduce Tor's privileges. (Default: 0)
 
 
+**DisableDebuggerAttachment** **0**|**1**::
+   If set to 1, Tor will attempt to prevent basic debugging attachment attempts
+   by other processes. It has no impact for users who wish to attach if they
+   have CAP_SYS_PTRACE or if they are root.  We believe that this feature
+   works on modern Gnu/Linux distributions, and that it may also work on *BSD
+   systems (untested).  Some modern Gnu/Linux systems such as Ubuntu have the
+   kernel.yama.ptrace_scope sysctl and by default enable it as an attempt to
+   limit the PTRACE scope for all user processes by default. This feature will
+   attempt to limit the PTRACE scope for Tor specifically - it will not attempt
+   to alter the system wide ptrace scope as it may not even exist. If you wish
+   to attach to Tor with a debugger such as gdb or strace you will want to set
+   this to 0 for the duration of your debugging. Normal users should leave it
+   on. (Default: 1)
+ 
 **FetchDirInfoEarly** **0**|**1**::
 **FetchDirInfoEarly** **0**|**1**::
     If set to 1, Tor will always fetch directory information like other
     If set to 1, Tor will always fetch directory information like other
     directory caches, even if you don't meet the normal criteria for fetching
     directory caches, even if you don't meet the normal criteria for fetching

+ 57 - 0
src/or/config.c

@@ -45,6 +45,14 @@
 /* From main.c */
 /* From main.c */
 extern int quiet_level;
 extern int quiet_level;
 
 
+/* Includes for the process attaching prevention */
+#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
+#include <sys/prctl.h> 
+#elif defined(__APPLE__)
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#endif
+
 /** Enumeration of types which option values can take */
 /** Enumeration of types which option values can take */
 typedef enum config_type_t {
 typedef enum config_type_t {
   CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
   CONFIG_TYPE_STRING = 0,   /**< An arbitrary string. */
@@ -246,6 +254,7 @@ static config_var_t _option_vars[] = {
   V(DirReqStatistics,            BOOL,     "1"),
   V(DirReqStatistics,            BOOL,     "1"),
   VAR("DirServer",               LINELIST, DirServers, NULL),
   VAR("DirServer",               LINELIST, DirServers, NULL),
   V(DisableAllSwap,              BOOL,     "0"),
   V(DisableAllSwap,              BOOL,     "0"),
+  V(DisableDebuggerAttachment,   BOOL,     "1"),
   V(DisableIOCP,                 BOOL,     "1"),
   V(DisableIOCP,                 BOOL,     "1"),
   V(DNSPort,                     LINELIST, NULL),
   V(DNSPort,                     LINELIST, NULL),
   V(DNSListenAddress,            LINELIST, NULL),
   V(DNSListenAddress,            LINELIST, NULL),
@@ -678,6 +687,47 @@ get_dirportfrontpage(void)
   return global_dirfrontpagecontents;
   return global_dirfrontpagecontents;
 }
 }
 
 
+/* We only use the linux prctl for now. There is no Win32 support; this may
+ * also work on various BSD systems and Mac OS X - send testing feedback!
+ * 
+ * On recent Gnu/Linux kernels it is possible to create a system-wide policy
+ * that will prevent non-root processes from attaching to other processes
+ * unless they are the parent process; thus gdb can attach to programs that
+ * they execute but they cannot attach to other processes running as the same
+ * user. The system wide policy may be set with the sysctl
+ * kernel.yama.ptrace_scope or by inspecting /proc/sys/kernel/yama/ptrace_scope
+ * and it is 1 by default on Ubuntu 11.04.
+ *
+ * This ptrace scope will be ignored on Gnu/Linux for users with
+ * CAP_SYS_PTRACE and so it is very likely that root will still be able to
+ * attach to the Tor process.
+*/
+/** Attempt to disable debugger attachment. */
+static int tor_disable_debugger_attach(void) {
+    int r;
+    r = -1;
+    log_debug(LD_CONFIG,
+    "Attemping to disable debugger attachment to Tor for unprivileged users.");
+#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
+#ifdef PR_SET_DUMPABLE
+    r = prctl(PR_SET_DUMPABLE, 0);
+#endif
+#endif
+#if defined(__APPLE__) && defined(PT_DENY_ATTACH)
+    r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
+#endif
+
+// XXX: TODO - Mac OS X has dtrace and this may be disabled - implement it here
+// XXX: TODO - Windows probably has something similar - implement it here
+    if (r == 0) {
+      log_debug(LD_CONFIG,"Debugger attachment disabled for unprivileged users.");
+    } else {
+      log_warn(LD_CONFIG, "Unable to disable ptrace attach: %s",
+                          strerror(errno));
+    }
+    return r;
+}
+
 /** Allocate an empty configuration object of a given format type. */
 /** Allocate an empty configuration object of a given format type. */
 static void *
 static void *
 config_alloc(const config_format_t *fmt)
 config_alloc(const config_format_t *fmt)
@@ -1286,6 +1336,13 @@ options_act(const or_options_t *old_options)
   const int transition_affects_workers =
   const int transition_affects_workers =
     old_options && options_transition_affects_workers(old_options, options);
     old_options && options_transition_affects_workers(old_options, options);
 
 
+   /* disable ptrace and later, other basic debugging techniques */
+  if (options->DisableDebuggerAttachment) {
+      tor_disable_debugger_attach();
+  } else {
+      log_notice(LD_CONFIG,"Debugger attachment enabled for unprivileged users.");
+  }
+ 
   if (running_tor && !have_lockfile()) {
   if (running_tor && !have_lockfile()) {
     if (try_locking(options, 1) < 0)
     if (try_locking(options, 1) < 0)
       return -1;
       return -1;

+ 2 - 0
src/or/or.h

@@ -3248,6 +3248,8 @@ typedef struct {
                     disclaimer. This allows a server administrator to show
                     disclaimer. This allows a server administrator to show
                     that they're running Tor and anyone visiting their server
                     that they're running Tor and anyone visiting their server
                     will know this without any specialized knowledge. */
                     will know this without any specialized knowledge. */
+  int DisableDebuggerAttachment; /**< Currently Linux only specific attempt to
+                                      disable ptrace; needs BSD testing. */
   /** Boolean: if set, we start even if our resolv.conf file is missing
   /** Boolean: if set, we start even if our resolv.conf file is missing
    * or broken. */
    * or broken. */
   int ServerDNSAllowBrokenConfig;
   int ServerDNSAllowBrokenConfig;