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);

Reply via email to