From ff4b3c8939f7616b0b901104b71e8ac30ebc9ab9 Mon Sep 17 00:00:00 2001 From: smitsohu Date: Mon, 2 Mar 2020 14:16:17 +0100 Subject: integrate AppArmor with join options (#3242) add AppArmor confinement to processes started with --join and, more importantly, --join-or-start --- src/firejail/firejail.h | 1 + src/firejail/join.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++- src/firejail/sandbox.c | 34 +++++++++++++++++++------------ 3 files changed, 75 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 66328a55e..0e4fcea6a 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -359,6 +359,7 @@ char *guess_shell(void); // sandbox.c int sandbox(void* sandbox_arg); void start_application(int no_sandbox, FILE *fp); +void set_apparmor(void); // network_main.c void net_configure_sandbox_ip(Bridge *br); diff --git a/src/firejail/join.c b/src/firejail/join.c index 531f8c06a..fa1f64333 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -26,7 +26,11 @@ #include #ifndef PR_SET_NO_NEW_PRIVS -# define PR_SET_NO_NEW_PRIVS 38 +#define PR_SET_NO_NEW_PRIVS 38 +#endif + +#ifdef HAVE_APPARMOR +#include #endif static int apply_caps = 0; @@ -50,6 +54,46 @@ static void install_handler(void) { sigaction(SIGTERM, &sga, NULL); } +#ifdef HAVE_APPARMOR +static void extract_apparmor(pid_t pid) { + if (checkcfg(CFG_APPARMOR)) { + EUID_USER(); + if (aa_is_enabled() == 1) { + // get pid of next child process + pid_t child; + if (find_child(pid, &child) == 1) + child = pid; // no child, proceed with current pid + + // get name of AppArmor profile + char *fname; + if (asprintf(&fname, "/proc/%d/attr/current", child) == -1) + errExit("asprintf"); + EUID_ROOT(); + int fd = open(fname, O_RDONLY|O_CLOEXEC); + EUID_USER(); + free(fname); + if (fd == -1) + goto errexit; + char buf[BUFLEN]; + ssize_t rv = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (rv < 0) + goto errexit; + buf[rv] = '\0'; + // process confined by Firejail's AppArmor policy? + if (strncmp(buf, "firejail-default", 16) == 0) + arg_apparmor = 1; + } + EUID_ROOT(); + } + return; + +errexit: + fprintf(stderr, "Error: cannot read /proc file\n"); + exit(1); +} +#endif // HAVE_APPARMOR + static void extract_x11_display(pid_t pid) { char *fname; if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) @@ -388,6 +432,9 @@ void join(pid_t pid, int argc, char **argv, int index) { extract_cgroup(pid); extract_nogroups(pid); extract_user_namespace(pid); +#ifdef HAVE_APPARMOR + extract_apparmor(pid); +#endif } // set cgroup @@ -501,6 +548,11 @@ void join(pid_t pid, int argc, char **argv, int index) { // kill the child in case the parent died prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); +#ifdef HAVE_APPARMOR + // add apparmor confinement after the execve + set_apparmor(); +#endif + extract_command(argc, argv, index); if (cfg.command_line == NULL) { assert(cfg.shell); diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index d1d98f636..d1879fd98 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifndef CLONE_NEWUSER @@ -37,16 +38,15 @@ #include #ifndef PR_SET_NO_NEW_PRIVS -# define PR_SET_NO_NEW_PRIVS 38 +#define PR_SET_NO_NEW_PRIVS 38 #endif #ifndef PR_GET_NO_NEW_PRIVS -# define PR_GET_NO_NEW_PRIVS 39 +#define PR_GET_NO_NEW_PRIVS 39 #endif #ifdef HAVE_APPARMOR #include #endif -#include static int force_nonewprivs = 0; @@ -125,6 +125,21 @@ static void set_caps(void) { caps_drop_dac_override(); } +#ifdef HAVE_APPARMOR +void set_apparmor(void) { + EUID_ASSERT(); + if (checkcfg(CFG_APPARMOR) && arg_apparmor) { + if (aa_change_onexec("firejail-default")) { + fwarning("Cannot confine the application using AppArmor.\n" + "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n" + "As root, run \"aa-enforce firejail-default\" to load it.\n"); + } + else if (arg_debug) + printf("AppArmor enabled\n"); + } +} +#endif + static void save_nogroups(void) { if (arg_nogroups == 0) return; @@ -1203,17 +1218,10 @@ int sandbox(void* sandbox_arg) { if (app_pid == 0) { #ifdef HAVE_APPARMOR - if (checkcfg(CFG_APPARMOR) && arg_apparmor) { - errno = 0; - if (aa_change_onexec("firejail-default")) { - fwarning("Cannot confine the application using AppArmor.\n" - "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n" - "As root, run \"aa-enforce firejail-default\" to load it.\n"); - } - else if (arg_debug) - printf("AppArmor enabled\n"); - } + // add apparmor confinement after the execve + set_apparmor(); #endif + // set nice and rlimits if (arg_nice) set_nice(cfg.nice); -- cgit v1.2.3-54-g00ecf