Commit 4b800408 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Check permissions on the directory holding a control socket

parent 5d147d85
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
  o Minor features:
    - Tor now refuses to create a ControlSocket in a directory that is
      world-readable (or group-readable if ControlSocketsGroupWritable
      is 0).  This is necessary because some operating systems do not
      check the permissions on an AF_UNIX socket when programs try to
      connect to it.  Checking permissions on the directory holding
      the socket, however, seems to work everywhere.
+40 −0
Original line number Diff line number Diff line
@@ -853,6 +853,43 @@ warn_too_many_conns(void)
  }
}

#ifdef HAVE_SYS_UN_H
/** Check whether we should be willing to open an AF_UNIX socket in
 * <b>path</b>.  Return 0 if we should go ahead and -1 if we shouldn't. */
static int
check_location_for_unix_socket(or_options_t *options, const char *path)
{
  int r = -1;
  char *p = tor_strdup(path);
  cpd_check_t flags = CPD_CHECK_MODE_ONLY;
  if (get_parent_directory(p)<0)
    goto done;

  if (options->ControlSocketsGroupWritable)
    flags |= CPD_GROUP_OK;

  if (check_private_dir(p, flags) < 0) {
    char *escpath, *escdir;
    escpath = esc_for_log(path);
    escdir = esc_for_log(p);
    log_warn(LD_GENERAL, "Before Tor can create a control socket in %s, the "
             "directory %s needs to exist, and to be accessible only by the "
             "user%s account that is running Tor.  (On some Unix systems, "
             "anybody who can list a socket can conect to it, so Tor is "
             "being careful.)", escpath, escdir,
             options->ControlSocketsGroupWritable ? " and group" : "");
    tor_free(escpath);
    tor_free(escdir);
    goto done;
  }

  r = 0;
 done:
  tor_free(p);
  return r;
}
#endif

/** Bind a new non-blocking socket listening to the socket described
 * by <b>listensockaddr</b>.
 *
@@ -947,6 +984,9 @@ connection_create_listener(const struct sockaddr *listensockaddr,
     * and listeners at the same time */
    tor_assert(type == CONN_TYPE_CONTROL_LISTENER);

    if (check_location_for_unix_socket(get_options(), address) < 0)
      goto err;

    log_notice(LD_NET, "Opening %s on %s",
               conn_type_to_string(type), address);