void API minijail_enter(const struct minijail *j) { if (j->flags.pids) die("tried to enter a pid-namespaced jail;" "try minijail_run()?"); if (j->flags.usergroups && !j->user) die("usergroup inheritance without username"); /* * We can't recover from failures if we've dropped privileges partially, * so we don't even try. If any of our operations fail, we abort() the * entire process. */ if (j->flags.vfs && unshare(CLONE_NEWNS)) pdie("unshare(vfs)"); if (j->flags.net && unshare(CLONE_NEWNET)) pdie("unshare(net)"); if (j->flags.chroot && enter_chroot(j)) pdie("chroot"); if (j->flags.chroot && j->flags.mount_tmp && mount_tmp()) pdie("mount_tmp"); if (j->flags.readonly && remount_readonly(j)) pdie("remount"); if (j->flags.caps) { /* * POSIX capabilities are a bit tricky. If we drop our * capability to change uids, our attempt to use setuid() * below will fail. Hang on to root caps across setuid(), then * lock securebits. */ if (prctl(PR_SET_KEEPCAPS, 1)) pdie("prctl(PR_SET_KEEPCAPS)"); if (prctl (PR_SET_SECUREBITS, SECURE_ALL_BITS | SECURE_ALL_LOCKS)) pdie("prctl(PR_SET_SECUREBITS)"); } /* * If we're setting no_new_privs, we can drop privileges * before setting seccomp filter. This way filter policies * don't need to allow privilege-dropping syscalls. */ if (j->flags.no_new_privs) { drop_ugid(j); if (j->flags.caps) drop_caps(j); set_seccomp_filter(j); } else { /* * If we're not setting no_new_privs, * we need to set seccomp filter *before* dropping privileges. * WARNING: this means that filter policies *must* allow * setgroups()/setresgid()/setresuid() for dropping root and * capget()/capset()/prctl() for dropping caps. */ set_seccomp_filter(j); drop_ugid(j); if (j->flags.caps) drop_caps(j); } /* * seccomp has to come last since it cuts off all the other * privilege-dropping syscalls :) */ if (j->flags.seccomp && prctl(PR_SET_SECCOMP, 1)) pdie("prctl(PR_SET_SECCOMP)"); }
void run_hooks_in_chroot() { ensure_we_can_find_in_chroot_hooks(); g_assert(enter_chroot()); run_hooks(&in_chroot_info); }