commit:     f0d8469ab6f3a4039038bf86cc829e917b596f40
Author:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 22 00:20:58 2021 +0000
Commit:     Mike Frysinger <vapier <AT> gentoo <DOT> org>
CommitDate: Sun Oct 24 00:54:46 2021 +0000
URL:        https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=f0d8469a

sandbox: leverage PR_SET_NO_NEW_PRIVS when available

This will lock down the ability to use set*id programs (like sudo),
and will allow us to utilize seccomp bpf to speed up ptrace.

Closes: https://bugs.gentoo.org/442172
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org>

 configure.ac  |  2 ++
 headers.h     |  3 +++
 src/sandbox.c | 16 ++++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/configure.ac b/configure.ac
index 0f2b0ea..fef865f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -133,6 +133,7 @@ AC_CHECK_HEADERS_ONCE(m4_flatten([
        sys/mman.h
        sys/mount.h
        sys/param.h
+       sys/prctl.h
        sys/ptrace.h
        sys/reg.h
        sys/socket.h
@@ -209,6 +210,7 @@ AC_CHECK_FUNCS_ONCE(m4_flatten([
        openat
        openat64
        pathconf
+       prctl
        process_vm_readv
        ptrace
        realpath

diff --git a/headers.h b/headers.h
index 605413e..396002f 100644
--- a/headers.h
+++ b/headers.h
@@ -113,6 +113,9 @@
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
 #endif
+#ifdef HAVE_SYS_PRCTL_H
+# include <sys/prctl.h>
+#endif
 #ifdef HAVE_SYS_PTRACE_H
 # include <sys/ptrace.h>
 #endif

diff --git a/src/sandbox.c b/src/sandbox.c
index 7582dee..d74abd9 100644
--- a/src/sandbox.c
+++ b/src/sandbox.c
@@ -278,6 +278,22 @@ int main(int argc, char **argv)
                }
        }
 
+#ifdef HAVE_PRCTL
+       /* Lock down access to elevated privileges.  In practice, this will 
block
+        * use of tools like su and sudo, and will allow use of seccomp bpf.
+        */
+# ifdef PR_SET_NO_NEW_PRIVS
+       if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
+               /* Ignore EINVAL in case we're on old kernels.  Unfortunately 
we can't
+                * differentiate between EINVAL due to unsupported PR_xxx and 
EINVAL
+                * due to bad 2nd/3rd/4th/5th args.
+                */
+               if (errno != EINVAL)
+                       sb_eerror("prctl(PR_SET_NO_NEW_PRIVS) failed");
+       }
+# endif
+#endif
+
        /* Set up the required signal handlers */
        int sigs[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, };
        struct sigaction act_new, act_old[ARRAY_SIZE(sigs)];

Reply via email to