mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge remote-tracking branch 'tor-gitlab/mr/205'
This commit is contained in:
commit
c05ae61f26
@ -19,9 +19,11 @@
|
|||||||
#include "lib/fs/path.h"
|
#include "lib/fs/path.h"
|
||||||
#include "lib/log/log.h"
|
#include "lib/log/log.h"
|
||||||
#include "lib/malloc/malloc.h"
|
#include "lib/malloc/malloc.h"
|
||||||
|
#include "lib/sandbox/sandbox.h"
|
||||||
#include "lib/string/printf.h"
|
#include "lib/string/printf.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
static smartlist_t *config_get_file_list(const char *path,
|
static smartlist_t *config_get_file_list(const char *path,
|
||||||
smartlist_t *opened_files);
|
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);
|
opened_lst, 1, NULL, config_process_include);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a list of paths obtained when expading globs in <b>pattern</b>. If
|
/** Return a list of paths obtained when expading globs in <b>pattern</b>.
|
||||||
* <b>pattern</b> has no globs, returns a list with <b>pattern</b> if it is an
|
* If <b>pattern</b> has no globs, return a list with <b>pattern</b> in it.
|
||||||
* existing path or NULL otherwise. If <b>opened_files</b> is provided, adds
|
* If <b>opened_files</b> is provided, add paths opened by glob to it.
|
||||||
* paths opened by glob to it. Returns NULL on failure. */
|
* Return NULL on failure. */
|
||||||
static smartlist_t *
|
static smartlist_t *
|
||||||
expand_glob(const char *pattern, smartlist_t *opened_files)
|
expand_glob(const char *pattern, smartlist_t *opened_files)
|
||||||
{
|
{
|
||||||
smartlist_t *matches = tor_glob(pattern);
|
if (! has_glob(pattern)) {
|
||||||
if (!matches) {
|
smartlist_t *matches = smartlist_new();
|
||||||
return NULL;
|
smartlist_add_strdup(matches, pattern);
|
||||||
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it is not a glob, return error when the path is missing
|
smartlist_t *matches = tor_glob(pattern);
|
||||||
if (!has_glob(pattern) && smartlist_len(matches) == 0) {
|
if (!matches) {
|
||||||
smartlist_free(matches);
|
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);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +114,13 @@ config_get_file_list(const char *pattern, smartlist_t *opened_files)
|
|||||||
if (opened_files) {
|
if (opened_files) {
|
||||||
smartlist_add_strdup(opened_files, path);
|
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);
|
file_status_t file_type = file_status(path);
|
||||||
if (file_type == FN_FILE) {
|
if (file_type == FN_FILE) {
|
||||||
@ -201,6 +215,13 @@ config_process_include(const char *pattern, int recursion_level, int extended,
|
|||||||
|
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
|
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);
|
log_notice(LD_CONFIG, "Including configuration file \"%s\".", config_file);
|
||||||
config_line_t *included_config = NULL;
|
config_line_t *included_config = NULL;
|
||||||
config_line_t *included_config_last = NULL;
|
config_line_t *included_config_last = NULL;
|
||||||
|
@ -537,6 +537,10 @@ unglob_win32(const char *pattern, int prev_sep, int next_sep)
|
|||||||
static DIR *
|
static DIR *
|
||||||
prot_opendir(const char *name)
|
prot_opendir(const char *name)
|
||||||
{
|
{
|
||||||
|
if (sandbox_interned_string_is_missing(name)) {
|
||||||
|
errno = EPERM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return opendir(sandbox_intern_string(name));
|
return opendir(sandbox_intern_string(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,6 +548,10 @@ prot_opendir(const char *name)
|
|||||||
static int
|
static int
|
||||||
prot_stat(const char *pathname, struct stat *buf)
|
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);
|
return stat(sandbox_intern_string(pathname), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,6 +559,10 @@ prot_stat(const char *pathname, struct stat *buf)
|
|||||||
static int
|
static int
|
||||||
prot_lstat(const char *pathname, struct stat *buf)
|
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);
|
return lstat(sandbox_intern_string(pathname), buf);
|
||||||
}
|
}
|
||||||
/** As closedir, but has the right type for gl_closedir */
|
/** 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
|
/** 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
|
* <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 *
|
struct smartlist_t *
|
||||||
tor_glob(const char *pattern)
|
tor_glob(const char *pattern)
|
||||||
|
@ -310,6 +310,8 @@ static int filter_nopar_gen[] = {
|
|||||||
#define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
|
#define seccomp_rule_add_4(ctx,act,call,f1,f2,f3,f4) \
|
||||||
seccomp_rule_add((ctx),(act),(call),4,(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
|
* Function responsible for setting up the rt_sigaction syscall for
|
||||||
* the seccomp filter sandbox.
|
* the seccomp filter sandbox.
|
||||||
@ -1224,8 +1226,41 @@ static sandbox_filter_func_t filter_func[] = {
|
|||||||
sb_kill
|
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 *
|
const char *
|
||||||
sandbox_intern_string(const char *str)
|
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;
|
sandbox_cfg_t *elem;
|
||||||
|
|
||||||
@ -1245,9 +1280,7 @@ sandbox_intern_string(const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sandbox_active)
|
return NULL;
|
||||||
log_warn(LD_BUG, "No interned sandbox parameter found for %s", str);
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DOCDOC */
|
/* DOCDOC */
|
||||||
|
@ -104,12 +104,11 @@ typedef struct {
|
|||||||
#endif /* defined(USE_LIBSECCOMP) */
|
#endif /* defined(USE_LIBSECCOMP) */
|
||||||
|
|
||||||
#ifdef 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);
|
const char* sandbox_intern_string(const char *param);
|
||||||
|
bool sandbox_interned_string_is_missing(const char *s);
|
||||||
#else /* !defined(USE_LIBSECCOMP) */
|
#else /* !defined(USE_LIBSECCOMP) */
|
||||||
#define sandbox_intern_string(s) (s)
|
#define sandbox_intern_string(s) (s)
|
||||||
|
#define sandbox_interned_string_is_missing(s) (false)
|
||||||
#endif /* defined(USE_LIBSECCOMP) */
|
#endif /* defined(USE_LIBSECCOMP) */
|
||||||
|
|
||||||
/** Creates an empty sandbox configuration file.*/
|
/** Creates an empty sandbox configuration file.*/
|
||||||
|
Loading…
Reference in New Issue
Block a user