aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2019-04-28 17:56:30 +0200
committerKarel Kočí <cynerd@email.cz>2019-04-28 17:56:30 +0200
commit68f78d914b221763476e6f17a0d0c48183eeb8cb (patch)
tree9f65bcd596ed9dbc551e6a8b39067f5e4169db7d
parent3f0fa5587f6e69e8957e674d3ccde6ff8873302e (diff)
downloaduroot-68f78d914b221763476e6f17a0d0c48183eeb8cb.tar.gz
uroot-68f78d914b221763476e6f17a0d0c48183eeb8cb.tar.bz2
uroot-68f78d914b221763476e6f17a0d0c48183eeb8cb.zip
child: allow binfmt_misc to be preserved
This should allow chrooting to non-native systems using qemu.
-rw-r--r--child.c21
-rw-r--r--child.h2
-rw-r--r--main.c13
3 files changed, 26 insertions, 10 deletions
diff --git a/child.c b/child.c
index a9c5c26..d25df85 100644
--- a/child.c
+++ b/child.c
@@ -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();
diff --git a/child.h b/child.h
index 18909e4..cb49638 100644
--- a/child.h
+++ b/child.h
@@ -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
diff --git a/main.c b/main.c
index 0f4815c..058aa3b 100644
--- a/main.c
+++ b/main.c
@@ -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];