From e9166dc417066e90bd2e544f0a2c79af159d43e7 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Thu, 14 Jan 2016 12:10:55 -0500 Subject: join command enhancements --- src/firejail/firejail.h | 2 ++ src/firejail/join.c | 39 ++++++++++++++++++++++++++------------- src/firejail/main.c | 35 +++++++++++++++++++++++++++++++++++ src/firejail/usage.c | 8 ++++++++ src/man/firejail.txt | 28 ++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 38c464735..1de38c43a 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -227,6 +227,8 @@ extern int arg_scan; // arp-scan all interfaces extern int arg_whitelist; // whitelist commad extern int arg_nosound; // disable sound extern int arg_quiet; // no output for scripting +extern int arg_join_network; // join only the network namespace +extern int arg_join_filesystem; // join only the mount namespace extern int parent_to_child_fds[2]; extern int child_to_parent_fds[2]; diff --git a/src/firejail/join.c b/src/firejail/join.c index ca9ec33e9..b05e25387 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -236,16 +236,26 @@ void join(pid_t pid, const char *homedir, int argc, char **argv, int index) { set_cgroup(cfg.cgroup); // join namespaces - if (join_namespace(pid, "ipc")) - exit(1); - if (join_namespace(pid, "net")) - exit(1); - if (join_namespace(pid, "pid")) - exit(1); - if (join_namespace(pid, "uts")) - exit(1); - if (join_namespace(pid, "mnt")) - exit(1); + if (arg_join_network) { + if (join_namespace(pid, "net")) + exit(1); + } + else if (arg_join_filesystem) { + if (join_namespace(pid, "mnt")) + exit(1); + } + else { + if (join_namespace(pid, "ipc")) + exit(1); + if (join_namespace(pid, "net")) + exit(1); + if (join_namespace(pid, "pid")) + exit(1); + if (join_namespace(pid, "uts")) + exit(1); + if (join_namespace(pid, "mnt")) + exit(1); + } pid_t child = fork(); if (child < 0) @@ -256,9 +266,12 @@ void join(pid_t pid, const char *homedir, int argc, char **argv, int index) { if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) errExit("asprintf"); - int rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option - if (rv == 0) - printf("changing root to %s\n", rootdir); + int rv; + if (!arg_join_network) { + rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option + if (rv == 0) + printf("changing root to %s\n", rootdir); + } prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died if (chdir("/") < 0) diff --git a/src/firejail/main.c b/src/firejail/main.c index 7d2fbba9c..58d735010 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -89,6 +89,9 @@ int arg_scan = 0; // arp-scan all interfaces int arg_whitelist = 0; // whitelist commad int arg_nosound = 0; // disable sound int arg_quiet = 0; // no output for scripting +int arg_join_network = 0; // join only the network namespace +int arg_join_filesystem = 0; // join only the mount namespace + int parent_to_child_fds[2]; int child_to_parent_fds[2]; @@ -394,6 +397,38 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { join_name(argv[i] + 7, cfg.homedir, argc, argv, i + 1); exit(0); } + else if (strncmp(argv[i], "--join-network=", 15) == 0) { + logargs(argc, argv); + arg_join_network = 1; + if (getuid() != 0) { + fprintf(stderr, "Error: --join-network is only available to root user\n"); + exit(1); + } + + // join sandbox by pid or by name + pid_t pid; + if (read_pid(argv[i] + 15, &pid) == 0) + join(pid, cfg.homedir, argc, argv, i + 1); + else + join_name(argv[i] + 15, cfg.homedir, argc, argv, i + 1); + exit(0); + } + else if (strncmp(argv[i], "--join-filesystem=", 18) == 0) { + logargs(argc, argv); + arg_join_filesystem = 1; + if (getuid() != 0) { + fprintf(stderr, "Error: --join-filesystem is only available to root user\n"); + exit(1); + } + + // join sandbox by pid or by name + pid_t pid; + if (read_pid(argv[i] + 18, &pid) == 0) + join(pid, cfg.homedir, argc, argv, i + 1); + else + join_name(argv[i] + 18, cfg.homedir, argc, argv, i + 1); + exit(0); + } else if (strncmp(argv[i], "--shutdown=", 11) == 0) { logargs(argc, argv); diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 3689f7b22..9197baae2 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -113,6 +113,14 @@ void usage(void) { printf("\t\tthe sandbox is started as root.\n\n"); printf("\t--join=name - join the sandbox identified by name.\n\n"); printf("\t--join=pid - join the sandbox identified by PID.\n\n"); + printf("\t--join-filesystem=name - join the mount namespace of the sandbox\n"); + printf("\t\tidentified by name.\n\n"); + printf("\t--join-filesystem=pid - join the mount namespace of the sandbox\n"); + printf("\t\tidentified by PID.\n\n"); + printf("\t--join-network=name - join the network namespace of the sandbox\n"); + printf("\t\tidentified by name.\n\n"); + printf("\t--join-network=pid - join the network namespace of the sandbox\n"); + printf("\t\tidentified by PID.\n\n"); printf("\t--list - list all sandboxes.\n\n"); printf("\t--mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n\n"); printf("\t--mtu=number - set interface MTU.\n\n"); diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 895b7a3af..66ec40ce9 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -530,6 +530,34 @@ $ firejail \-\-list .br $ firejail \-\-join=3272 +.TP +\fB\-\-join-filesystem=name +Join the mount namespace of the sandbox identified by name. By default a /bin/bash shell is started after joining the sandbox. +If a program is specified, the program is run in the sandbox. This command is available only to root user. +Security filters, cgroups and cpus configurations are not applied to the process joining the sandbox. + +.TP +\fB\-\-join-filesystem=pid +Join the mount namespace of the sandbox identified by process ID. By default a /bin/bash shell is started after joining the sandbox. +If a program is specified, the program is run in the sandbox. This command is available only to root user. +Security filters, cgroups and cpus configurations are not applied to the process joining the sandbox. + +.TP +\fB\-\-join-network=name +Join the network namespace of the sandbox identified by name. By default a /bin/bash shell is started after joining the sandbox. +If a program is specified, the program is run in the sandbox. This command is available only to root user. +Security filters, cgroups and cpus configurations are not applied to the process joining the sandbox. + +.TP +\fB\-\-join-network=pid +Join the network namespace of the sandbox identified by process ID. By default a /bin/bash shell is started after joining the sandbox. +If a program is specified, the program is run in the sandbox. This command is available only to root user. +Security filters, cgroups and cpus configurations are not applied to the process joining the sandbox. + + + + + .TP \fB\-\-list List all sandboxes, see \fBMONITORING\fR section for more details. -- cgit v1.2.3-70-g09d2