diff options
-rw-r--r-- | child.c | 21 | ||||
-rw-r--r-- | child.h | 2 | ||||
-rw-r--r-- | main.c | 13 |
3 files changed, 26 insertions, 10 deletions
@@ -27,24 +27,27 @@ #include <assert.h> #include "utils.h" +#define PROC_BINFMT "/proc/sys/fs/binfmt_misc" + int child_main(void *_args) { struct child_args *args = _args; sigpipe_wait(args->sigpipe); - // Change some mount points to private + // Change all mount points to private mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL); assert_perror(errno); - /* - mount("none", "/proc", NULL, MS_REC | MS_PRIVATE, NULL); - assert_perror(errno); - mount("none", "/sys", NULL, MS_REC | MS_PRIVATE, NULL); - assert_perror(errno); - */ + // Mount new proc filesystem for this namespace + if (args->binfmt) { + mount(PROC_BINFMT, "/tmp", NULL, MS_BIND, NULL); + assert_perror(errno); + } mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC, NULL); assert_perror(errno); - //mount("binfmt_misc", "/proc/sys/fs/binfmt_misc", "binfmt_misc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL); - //assert_perror(errno); + if (args->binfmt) { + mount("/tmp", PROC_BINFMT, NULL, MS_MOVE, NULL); + assert_perror(errno); + } if (args->argc <= 1) { const char *shell = get_shell(); @@ -20,6 +20,7 @@ #ifndef _UROOT_CHILD_H_ #define _UROOT_CHILD_H_ +#include <stdbool.h> #include <sys/types.h> #include "sigpipe.h" @@ -29,6 +30,7 @@ struct child_args { int argc; char **argv; sigpipe_t sigpipe; + bool binfmt; }; // Function used as a main for child process @@ -41,10 +41,16 @@ static const char doc[] = "Tool using Linux namespaces to provide root like func struct opts { char **child_argv; size_t child_argc; + bool binfmt; +}; + +enum option_key { + OPT_BINFMT = 260, }; static struct argp_option options[] = { {"debug", 'd', NULL, 0, "Report uroot operations.", 0}, + {"binfmt", OPT_BINFMT, NULL, 0, "Preserve registered misc binary format handlers.", 0}, {NULL} }; @@ -54,6 +60,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { case 'd': // TODO logging break; + case OPT_BINFMT: + opts->binfmt = true; + break; case ARGP_KEY_ARGS: opts->child_argc = state->argc - state->next; opts->child_argv = malloc((opts->child_argc + 1) * sizeof *opts->child_argv); @@ -64,6 +73,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) { case ARGP_KEY_INIT: opts->child_argv = NULL; opts->child_argc = 0; + opts->binfmt = false; break; default: return ARGP_ERR_UNKNOWN; @@ -87,7 +97,8 @@ int main(int argc, char **argv) { .ppid = getpid(), .argc = opts.child_argc, .argv = opts.child_argv, - .sigpipe = sigpipe_new() + .sigpipe = sigpipe_new(), + .binfmt = opts.binfmt, }; uint8_t stack[STACK_SIZE]; |