commit: c4bf07615cd2e2ec25a16420d8ddee2efec6f8d2 Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> AuthorDate: Mon Oct 18 06:47:59 2021 +0000 Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> CommitDate: Mon Oct 18 06:47:59 2021 +0000 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=c4bf0761
libsandbox: add SANDBOX_METHOD setting This allows people to disable use of ptrace if their configuration does not support it. This forces older sandbox behavior where we cannot protect against static or set*id programs. Bug: https://bugs.gentoo.org/648516 Bug: https://bugs.gentoo.org/771360 Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> etc/sandbox.conf | 11 ++++++++++ libsandbox/libsandbox.c | 10 +++++++++ libsandbox/libsandbox.h | 1 + libsandbox/wrapper-funcs/__wrapper_exec.c | 4 ++++ libsbutil/Makefile.am | 1 + libsbutil/sb_method.c | 34 +++++++++++++++++++++++++++++++ libsbutil/sbutil.h | 11 ++++++++++ src/environ.c | 3 +++ 8 files changed, 75 insertions(+) diff --git a/etc/sandbox.conf b/etc/sandbox.conf index 2501e11..0d29a64 100644 --- a/etc/sandbox.conf +++ b/etc/sandbox.conf @@ -27,6 +27,17 @@ # Determine the use of color in the output. Default is "false" (ie, use color) #NOCOLOR="false" +# SANDBOX_METHOD +# +# Control how processes are monitored. See the README for system requirements +# for each setting, as well as particular limitations. Changing this setting +# is not recommended. +# +# Possible values: +# any: (default) Use any method of tracing available on the system. +# preload: Only use in-process LD_PRELOAD symbol interposing. +#SANDBOX_METHOD="any" + # # Namespace Section (Linux-only) diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c index 758c0dc..02f5ef2 100644 --- a/libsandbox/libsandbox.c +++ b/libsandbox/libsandbox.c @@ -29,6 +29,7 @@ char sandbox_lib[SB_PATH_MAX]; typedef struct { bool show_access_violation, on, active, testing, verbose, debug; + sandbox_method_t method; char *ld_library_path; char **prefixes[5]; int num_prefixes[5]; @@ -94,6 +95,7 @@ void libsb_init(void) sbcontext.verbose = is_env_on(ENV_SANDBOX_VERBOSE); sbcontext.debug = is_env_on(ENV_SANDBOX_DEBUG); sbcontext.testing = is_env_on(ENV_SANDBOX_TESTING); + sbcontext.method = get_sandbox_method(); if (sbcontext.testing) { const char *ldpath = getenv("LD_LIBRARY_PATH"); if (ldpath) @@ -101,6 +103,11 @@ void libsb_init(void) } } +sandbox_method_t get_sandbox_method(void) +{ + return parse_sandbox_method(getenv(ENV_SANDBOX_METHOD)); +} + /* resolve_dirfd_path - get the path relative to a dirfd * * return value: @@ -1170,6 +1177,7 @@ struct sb_envp_ctx sb_new_envp(char **envp, bool insert) ENV_PAIR(11, ENV_SANDBOX_DEBUG, NULL), ENV_PAIR(12, "LD_LIBRARY_PATH", NULL), ENV_PAIR(13, ENV_SANDBOX_TESTING, NULL), + ENV_PAIR(14, ENV_SANDBOX_METHOD, NULL), }; size_t num_vars = ARRAY_SIZE(vars); char *found_vars[num_vars]; @@ -1242,6 +1250,8 @@ struct sb_envp_ctx sb_new_envp(char **envp, bool insert) vars[12].value = sbcontext.ld_library_path; vars[13].value = "1"; } + if (sbcontext.method != SANDBOX_METHOD_ANY) + vars[14].value = str_sandbox_method(sbcontext.method); char ** my_env = NULL; if (!insert) { diff --git a/libsandbox/libsandbox.h b/libsandbox/libsandbox.h index 70fc422..96bb7c1 100644 --- a/libsandbox/libsandbox.h +++ b/libsandbox/libsandbox.h @@ -51,6 +51,7 @@ bool before_syscall(int, int, const char *, const char *, int); bool before_syscall_access(int, int, const char *, const char *, int); bool before_syscall_open_int(int, int, const char *, const char *, int); bool before_syscall_open_char(int, int, const char *, const char *, const char *); +enum sandbox_method_t get_sandbox_method(void); void *get_dlsym(const char *symname, const char *symver); diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c index 766245a..5174d2f 100644 --- a/libsandbox/wrapper-funcs/__wrapper_exec.c +++ b/libsandbox/wrapper-funcs/__wrapper_exec.c @@ -30,6 +30,10 @@ static bool sb_check_exec(const char *filename, char *const argv[]) struct stat st; bool do_trace = false; bool run_in_process = true; + sandbox_method_t method = get_sandbox_method(); + + if (unlikely(method == SANDBOX_METHOD_PRELOAD)) + return true; fd = sb_unwrapped_open_DEFAULT(filename, O_RDONLY|O_CLOEXEC, 0); if (fd == -1) diff --git a/libsbutil/Makefile.am b/libsbutil/Makefile.am index 684d126..06de7d3 100644 --- a/libsbutil/Makefile.am +++ b/libsbutil/Makefile.am @@ -22,6 +22,7 @@ libsbutil_la_SOURCES = \ sb_backtrace.c \ sb_efuncs.c \ sb_gdb.c \ + sb_method.c \ sb_open.c \ sb_read.c \ sb_write.c \ diff --git a/libsbutil/sb_method.c b/libsbutil/sb_method.c new file mode 100644 index 0000000..b2d62a7 --- /dev/null +++ b/libsbutil/sb_method.c @@ -0,0 +1,34 @@ +/* + * sb_method.c + * + * Util functions for sandbox method settings. + * + * Copyright 2021 Gentoo Foundation + * Licensed under the GPL-2 + */ + +#include "headers.h" +#include "sbutil.h" + +sandbox_method_t parse_sandbox_method(const char *method) +{ + if (method == NULL || streq(method, "") || streq(method, "any")) + return SANDBOX_METHOD_ANY; + + if (streq(method, "preload")) + return SANDBOX_METHOD_PRELOAD; + + return SANDBOX_METHOD_ANY; +} + +const char *str_sandbox_method(sandbox_method_t method) +{ + switch (method) { + case SANDBOX_METHOD_PRELOAD: + return "preload"; + case SANDBOX_METHOD_ANY: + return "any"; + default: + return ""; + } +} diff --git a/libsbutil/sbutil.h b/libsbutil/sbutil.h index 66c6f73..5194dde 100644 --- a/libsbutil/sbutil.h +++ b/libsbutil/sbutil.h @@ -54,6 +54,7 @@ #define ENV_SANDBOX_WRITE "SANDBOX_WRITE" #define ENV_SANDBOX_PREDICT "SANDBOX_PREDICT" +#define ENV_SANDBOX_METHOD "SANDBOX_METHOD" #define ENV_SANDBOX_ON "SANDBOX_ON" #define ENV_SANDBOX_ACTIVE "SANDBOX_ACTIVE" @@ -84,6 +85,13 @@ static inline bool is_env_var(const char *env, const char *var, size_t vlen) return !strncmp(env, var, vlen) && env[vlen] == '='; } +typedef enum sandbox_method_t { + SANDBOX_METHOD_ANY = 0, + SANDBOX_METHOD_PRELOAD, +} sandbox_method_t; +sandbox_method_t parse_sandbox_method(const char *); +const char *str_sandbox_method(sandbox_method_t); + /* proc helpers */ extern const char sb_fd_dir[]; #define sb_get_fd_dir() sb_fd_dir @@ -145,6 +153,9 @@ char *__xstrndup(const char *str, size_t size, const char *file, const char *fun #define xstrndup(_str, _size) __xstrndup(_str, _size, __FILE__, __func__, __LINE__) #define xalloc_die() __sb_ebort(__FILE__, __func__, __LINE__, "out of memory") +/* string helpers */ +#define streq(s1, s2) (strcmp(s1, s2) == 0) + /* errno helpers */ #define save_errno() int old_errno = errno; #define restore_errno() errno = old_errno; diff --git a/src/environ.c b/src/environ.c index 346bc26..542dd64 100644 --- a/src/environ.c +++ b/src/environ.c @@ -195,6 +195,7 @@ static int setup_cfg_vars(struct sandbox_info_t *sandbox_info) setup_cfg_var(ENV_SANDBOX_VERBOSE); setup_cfg_var(ENV_SANDBOX_DEBUG); setup_cfg_var(ENV_NOCOLOR); + setup_cfg_var(ENV_SANDBOX_METHOD); if (-1 == setup_access_var(ENV_SANDBOX_DENY)) return -1; @@ -301,6 +302,8 @@ char **setup_environ(struct sandbox_info_t *sandbox_info) sb_setenv(&new_environ, ENV_SANDBOX_DEBUG, "0"); if (!getenv(ENV_NOCOLOR)) sb_setenv(&new_environ, ENV_NOCOLOR, "no"); + if (!getenv(ENV_SANDBOX_METHOD)) + sb_setenv(&new_environ, ENV_SANDBOX_METHOD, "any"); /* If LD_PRELOAD was not set, set it here, else do it below */ if (!have_ld_preload) sb_setenv(&new_environ, ENV_LD_PRELOAD, ld_preload_envvar);
