Commit c731a4ef authored by George Kadianakis's avatar George Kadianakis
Browse files

Merge remote-tracking branch 'tor-gitlab/mr/205' into maint-0.4.5

parents e74f168b bd0046c9
Loading
Loading
Loading
Loading
+31 −10
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@
#include "lib/fs/path.h"
#include "lib/log/log.h"
#include "lib/malloc/malloc.h"
#include "lib/sandbox/sandbox.h"
#include "lib/string/printf.h"

#include <stdbool.h>
#include <errno.h>

static smartlist_t *config_get_file_list(const char *path,
                                         smartlist_t *opened_files);
@@ -52,21 +54,26 @@ config_get_lines_include(const char *string, config_line_t **result,
                              opened_lst, 1, NULL, config_process_include);
}

/** Returns a list of paths obtained when expading globs in <b>pattern</b>. If
 * <b>pattern</b> has no globs, returns a list with <b>pattern</b> if it is an
 * existing path or NULL otherwise. If <b>opened_files</b> is provided, adds
 * paths opened by glob to it. Returns NULL on failure. */
/** Return a list of paths obtained when expading globs in <b>pattern</b>.
 * If <b>pattern</b> has no globs, return a list with <b>pattern</b> in it.
 * If <b>opened_files</b> is provided, add paths opened by glob to it.
 * Return NULL on failure. */
static smartlist_t *
expand_glob(const char *pattern, smartlist_t *opened_files)
{
  if (! has_glob(pattern)) {
    smartlist_t *matches = smartlist_new();
    smartlist_add_strdup(matches, pattern);
    return matches;
  }

  smartlist_t *matches = tor_glob(pattern);
  if (!matches) {
    return NULL;
    if (errno == EPERM) {
      log_err(LD_CONFIG, "Sandbox is active, but the configuration pattern "
              "\"%s\" listed with %%include would access files or folders not "
              "allowed by it. Cannot proceed.", pattern);
    }

  // if it is not a glob, return error when the path is missing
  if (!has_glob(pattern) && smartlist_len(matches) == 0) {
    smartlist_free(matches);
    return NULL;
  }

@@ -107,6 +114,13 @@ config_get_file_list(const char *pattern, smartlist_t *opened_files)
    if (opened_files) {
      smartlist_add_strdup(opened_files, path);
    }
    if (sandbox_interned_string_is_missing(path)) {
      log_err(LD_CONFIG, "Sandbox is active, but a new configuration "
              "file \"%s\" has been listed with %%include. Cannot proceed.",
              path);
      error_found = true;
      break;
    }

    file_status_t file_type = file_status(path);
    if (file_type == FN_FILE) {
@@ -201,6 +215,13 @@ config_process_include(const char *pattern, int recursion_level, int extended,

  int rv = -1;
  SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
    if (sandbox_interned_string_is_missing(config_file)) {
      log_err(LD_CONFIG, "Sandbox is active, but a new configuration "
              "file \"%s\" has been listed with %%include. Cannot proceed.",
              config_file);
      goto done;
    }

    log_notice(LD_CONFIG, "Including configuration file \"%s\".", config_file);
    config_line_t *included_config = NULL;
    config_line_t *included_config_last = NULL;
+14 −1
Original line number Diff line number Diff line
@@ -537,6 +537,10 @@ unglob_win32(const char *pattern, int prev_sep, int next_sep)
static DIR *
prot_opendir(const char *name)
{
  if (sandbox_interned_string_is_missing(name)) {
    errno = EPERM;
    return NULL;
  }
  return opendir(sandbox_intern_string(name));
}

@@ -544,6 +548,10 @@ prot_opendir(const char *name)
static int
prot_stat(const char *pathname, struct stat *buf)
{
  if (sandbox_interned_string_is_missing(pathname)) {
    errno = EPERM;
    return -1;
  }
  return stat(sandbox_intern_string(pathname), buf);
}

@@ -551,6 +559,10 @@ prot_stat(const char *pathname, struct stat *buf)
static int
prot_lstat(const char *pathname, struct stat *buf)
{
  if (sandbox_interned_string_is_missing(pathname)) {
    errno = EPERM;
    return -1;
  }
  return lstat(sandbox_intern_string(pathname), buf);
}
/** As closedir, but has the right type for gl_closedir */
@@ -563,7 +575,8 @@ wrap_closedir(void *arg)

/** Return a new list containing the paths that match the pattern
 * <b>pattern</b>. Return NULL on error. On POSIX systems, errno is set by the
 * glob function.
 * glob function or is set to EPERM if glob tried to access a file not allowed
 * by the seccomp sandbox.
 */
struct smartlist_t *
tor_glob(const char *pattern)
+36 −3
Original line number Diff line number Diff line
@@ -310,6 +310,8 @@ static int filter_nopar_gen[] = {
#define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4)      \
  seccomp_rule_add((ctx),(act),(call),4,(f1),(f2),(f3),(f4))

static const char *sandbox_get_interned_string(const char *str);

/**
 * Function responsible for setting up the rt_sigaction syscall for
 * the seccomp filter sandbox.
@@ -1224,8 +1226,41 @@ static sandbox_filter_func_t filter_func[] = {
    sb_kill
};

/**
 * Return the interned (and hopefully sandbox-permitted) string equal
 * to @a str.
 *
 * Return NULL if `str` is NULL, or `str` is not an interned string.
 **/
const char *
sandbox_intern_string(const char *str)
{
  const char *interned = sandbox_get_interned_string(str);

  if (sandbox_active && str != NULL && interned == NULL) {
    log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
  }

  return interned ? interned : str;
}

/**
 * Return true if the sandbox is running and we are missing an interned string
 * equal to @a str.
 */
bool
sandbox_interned_string_is_missing(const char *str)
{
  return sandbox_active && sandbox_get_interned_string(str) == NULL;
}

/**
 * Try to find and return the interned string equal to @a str.
 *
 * If there is no such string, return NULL.
 **/
static const char *
sandbox_get_interned_string(const char *str)
{
  sandbox_cfg_t *elem;

@@ -1245,9 +1280,7 @@ sandbox_intern_string(const char *str)
    }
  }

  if (sandbox_active)
    log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
  return str;
  return NULL;
}

/* DOCDOC */
+2 −3
Original line number Diff line number Diff line
@@ -104,12 +104,11 @@ typedef struct {
#endif /* defined(USE_LIBSECCOMP) */

#ifdef USE_LIBSECCOMP
/** Returns a registered protected string used with the sandbox, given that
 * it matches the parameter.
 */
const char* sandbox_intern_string(const char *param);
bool sandbox_interned_string_is_missing(const char *s);
#else /* !defined(USE_LIBSECCOMP) */
#define sandbox_intern_string(s) (s)
#define sandbox_interned_string_is_missing(s) (false)
#endif /* defined(USE_LIBSECCOMP) */

/** Creates an empty sandbox configuration file.*/