[tor-commits] [tor/master] Use tor_getpw{nam, uid} wrappers to fix bug 11946

nickm at torproject.org nickm at torproject.org
Thu May 15 02:52:43 UTC 2014


commit 9b4ac986cbe8867c24c8e77654a4b7e75f870738
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed May 14 13:53:14 2014 -0400

    Use tor_getpw{nam,uid} wrappers to fix bug 11946
    
    When running with User set, we frequently try to look up our
    information in the user database (e.g., /etc/passwd).  The seccomp2
    sandbox setup doesn't let us open /etc/passwd, and probably
    shouldn't.
    
    To fix this, we have a pair of wrappers for getpwnam and getpwuid.
    When a real call to getpwnam or getpwuid fails, they fall back to a
    cached value, if the uid/gid matches.
    
    (Granting access to /etc/passwd isn't possible with the way we
    handle opening files through the sandbox.  It's not desirable either.)
---
 changes/bug11946    |    5 +++++
 src/common/compat.c |    8 ++++----
 src/common/util.c   |   10 +++++-----
 src/or/connection.c |    4 ++--
 src/or/control.c    |    2 +-
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/changes/bug11946 b/changes/bug11946
new file mode 100644
index 0000000..9ea4831
--- /dev/null
+++ b/changes/bug11946
@@ -0,0 +1,5 @@
+  o Minor bugfixes (sandbox):
+
+    - Handle failures in getpwnam()/getpwuid() when running with the
+      User option set and the Linux syscall sandbox enabled. Fixes bug
+      11946; bugfix on 0.2.5.1-alpha.
diff --git a/src/common/compat.c b/src/common/compat.c
index 9f31cce..65446b5 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1792,7 +1792,7 @@ int
 switch_id(const char *user)
 {
 #ifndef _WIN32
-  struct passwd *pw = NULL;
+  const struct passwd *pw = NULL;
   uid_t old_uid;
   gid_t old_gid;
   static int have_already_switched_id = 0;
@@ -1813,7 +1813,7 @@ switch_id(const char *user)
   old_gid = getgid();
 
   /* Lookup the user and group information, if we have a problem, bail out. */
-  pw = getpwnam(user);
+  pw = tor_getpwnam(user);
   if (pw == NULL) {
     log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
     return -1;
@@ -1984,10 +1984,10 @@ tor_disable_debugger_attach(void)
 char *
 get_user_homedir(const char *username)
 {
-  struct passwd *pw;
+  const struct passwd *pw;
   tor_assert(username);
 
-  if (!(pw = getpwnam(username))) {
+  if (!(pw = tor_getpwnam(username))) {
     log_err(LD_CONFIG,"User \"%s\" not found.", username);
     return NULL;
   }
diff --git a/src/common/util.c b/src/common/util.c
index d573b56..d457ba9 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1871,7 +1871,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
   char *f;
 #ifndef _WIN32
   int mask;
-  struct passwd *pw = NULL;
+  const struct passwd *pw = NULL;
   uid_t running_uid;
   gid_t running_gid;
 #else
@@ -1918,7 +1918,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
   if (effective_user) {
     /* Look up the user and group information.
      * If we have a problem, bail out. */
-    pw = getpwnam(effective_user);
+    pw = tor_getpwnam(effective_user);
     if (pw == NULL) {
       log_warn(LD_CONFIG, "Error setting configured user: %s not found",
                effective_user);
@@ -1932,13 +1932,13 @@ check_private_dir(const char *dirname, cpd_check_t check,
   }
 
   if (st.st_uid != running_uid) {
-    struct passwd *pw = NULL;
+    const struct passwd *pw = NULL;
     char *process_ownername = NULL;
 
-    pw = getpwuid(running_uid);
+    pw = tor_getpwuid(running_uid);
     process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
 
-    pw = getpwuid(st.st_uid);
+    pw = tor_getpwuid(st.st_uid);
 
     log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
         "%s (%d). Perhaps you are running Tor as the wrong user?",
diff --git a/src/or/connection.c b/src/or/connection.c
index 3cc4e09..cef9172 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1017,7 +1017,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
   tor_socket_t s = TOR_INVALID_SOCKET;  /* the socket we're going to make */
   or_options_t const *options = get_options();
 #if defined(HAVE_PWD_H) && defined(HAVE_SYS_UN_H)
-  struct passwd *pw = NULL;
+  const struct passwd *pw = NULL;
 #endif
   uint16_t usePort = 0, gotPort = 0;
   int start_reading = 0;
@@ -1157,7 +1157,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
     }
 #ifdef HAVE_PWD_H
     if (options->User) {
-      pw = getpwnam(options->User);
+      pw = tor_getpwnam(options->User);
       if (pw == NULL) {
         log_warn(LD_NET,"Unable to chown() %s socket: user %s not found.",
                  address, options->User);
diff --git a/src/or/control.c b/src/or/control.c
index d571900..2865d78 100755
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1492,7 +1492,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
       *answer = tor_strdup("");
     #else
       int myUid = geteuid();
-      struct passwd *myPwEntry = getpwuid(myUid);
+      const struct passwd *myPwEntry = tor_getpwuid(myUid);
 
       if (myPwEntry) {
         *answer = tor_strdup(myPwEntry->pw_name);





More information about the tor-commits mailing list