commit b4cf0b2c84d26aadc22864ed48c6304738d523ea
parent 4c5f4a0c71ee0f1e3fa1db15b96b1eee03a077b9
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Wed, 12 Nov 2025 23:16:47 +0000
Restructure ns_pivot_into.c
Diffstat:
| M | src/ns_pivot_into.c | | | 89 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 51 insertions(+), 38 deletions(-)
diff --git a/src/ns_pivot_into.c b/src/ns_pivot_into.c
@@ -7,7 +7,9 @@
#include <sys/capability.h>
#include <sys/mount.h>
#include <sys/syscall.h> /* for SYS_pivot_root */
-#include <linux/securebits.h>
+#include <linux/filter.h> /* for seccomp */
+#include <linux/seccomp.h> /* for seccomp */
+#include <linux/securebits.h> /* for prctl(PR_SET_SECUREBITS, ...) */
#include <skalibs/types.h>
#include <skalibs/setgroups.h>
@@ -17,9 +19,10 @@
#include <skalibs/djbunix.h>
#include <skalibs/exec.h>
-#define USAGE "ns_pivot_into [ -U iab_caps ] [ -C chdir ] old-place-for-new-root new-place-for-old-root prog..."
+#define USAGE "ns_pivot_into [ -U iab_caps ] [ -S seccomp_bpf_fd ] [ -C chdir ] old-place-for-new-root new-place-for-old-root prog..."
#define dieusage() strerr_dieusage(100, USAGE)
+/*** data structures ***/
struct drop_privs_s {
uid_t uid;
gid_t gid;
@@ -33,39 +36,15 @@ struct unexport_s {
stralloc sa;
};
-void drop(struct drop_privs_s const *const privs) {
- /* make sure privileges are dropped permanently */
- if (prctl(PR_SET_SECUREBITS,
- SECBIT_KEEP_CAPS | /* technically unneeded as NO_SETUID_FIXUP is superset */
- SECBIT_NO_SETUID_FIXUP |
- SECBIT_NOROOT | /* disables suid and filecap privilege gain */
- SECBIT_NOROOT_LOCKED) < 0) {
- strerr_dief1sys(111, "Failed to set securebits via prctl()");
- }
-
- /* set these capabilities for the current process */
- if (cap_iab_set_proc(privs->new_iab) != 0) {
- strerr_dief1sys(111, "Failed to set capabilities via cap_set_proc()");
- }
-
- /* ancillary groups */
- if (privs->gidn != (size_t) -1
- && setgroups_and_gid(privs->gid ? privs->gid : getegid(), privs->gidn,
- privs->gids) < 0) {
- strerr_diefu1sys(111, "set supplementary group list");
- }
-
- /* primary group */
- if (privs->gid && setgid(privs->gid) < 0) {
- strerr_diefu1sys(111, "setgid");
- }
-
- /* set userid */
- if (privs->uid && setuid(privs->uid) < 0) {
- strerr_diefu1sys(111, "setuid");
- }
+/*** syscall wrappers ***/
+int syscall_pivot_root(char const *new_root, char const *put_old) {
+ return syscall(SYS_pivot_root, *new_root, *put_old);
+}
+int syscall_seccomp_set_filter(unsigned int flags, void *args) {
+ return syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, flags, args);
}
+/*** utility functions ***/
char const *const getenv_dienotset(char const *const name) {
char const *x = getenv(name);
if (!x) {
@@ -79,10 +58,7 @@ int stralloc_catenv0(stralloc *sa, char const * env_name) {
return stralloc_catb(sa, value, strlen(value) + 1);
}
-int pivot_root(char const *new_root, char const *put_old) {
- return syscall(SYS_pivot_root, *new_root, *put_old);
-}
-
+/*** individual steps of dropping into sandbox ***/
void pivot_and_umount(
char const *const old_place_for_new_root,
char const *const new_place_for_old_root,
@@ -114,7 +90,7 @@ void pivot_and_umount(
if (chdir(old_place_for_new_root) < 0) {
strerr_diefu2sys(111, "chdir to ", old_place_for_new_root) ;
}
- if (pivot_root(".", new_place_for_old_root) < 0) {
+ if (syscall_pivot_root(".", new_place_for_old_root) < 0) {
strerr_diefu1sys(111, "pivot_root") ;
}
if (chroot(".") < 0) {
@@ -155,6 +131,43 @@ void pivot_and_umount(
}
}
+void drop(struct drop_privs_s const *const privs) {
+ /* make sure privileges are dropped permanently */
+ if (prctl(PR_SET_SECUREBITS,
+ SECBIT_KEEP_CAPS | /* technically unneeded as NO_SETUID_FIXUP is superset */
+ SECBIT_NO_SETUID_FIXUP |
+ SECBIT_NOROOT | /* disables suid and filecap privilege gain */
+ SECBIT_NOROOT_LOCKED) < 0) {
+ strerr_dief1sys(111, "Failed to set securebits via prctl()");
+ }
+
+ /* set these capabilities for the current process */
+ if (cap_iab_set_proc(privs->new_iab) != 0) {
+ strerr_dief1sys(111, "Failed to set capabilities via cap_set_proc()");
+ }
+
+ /* ancillary groups */
+ if (privs->gidn != (size_t) -1
+ && setgroups_and_gid(privs->gid ? privs->gid : getegid(), privs->gidn,
+ privs->gids) < 0) {
+ strerr_diefu1sys(111, "set supplementary group list");
+ }
+
+ /* primary group */
+ if (privs->gid && setgid(privs->gid) < 0) {
+ strerr_diefu1sys(111, "setgid");
+ }
+
+ /* set userid */
+ if (privs->uid && setuid(privs->uid) < 0) {
+ strerr_diefu1sys(111, "setuid");
+ }
+}
+
+void load_seccomp_program(int fd) {
+ strerr_dief(99, "seccomp program loading not yet implemented");
+}
+
int main (int argc, char const *const *argv) {
struct unexport_s unex = { 0, STRALLOC_ZERO };
int drop_privs = 0;