diff --git a/bubblewrap.c b/bubblewrap.c index 771e1eaf..17aaa8bd 100644 --- a/bubblewrap.c +++ b/bubblewrap.c @@ -62,6 +62,7 @@ static const char *host_tty_dev; static int proc_fd = -1; static const char *opt_exec_label = NULL; static const char *opt_file_label = NULL; +static const char *opt_apparmor_profile = NULL; static bool opt_as_pid_1; const char *opt_chdir_path = NULL; @@ -253,6 +254,7 @@ usage (int ecode, FILE *out) " --remount-ro DEST Remount DEST as readonly; does not recursively remount\n" " --exec-label LABEL Exec label for the sandbox\n" " --file-label LABEL File label for temporary sandbox content\n" + " --apparmor-profile PROFILE AppArmor profile for the sandbox\n" " --proc DEST Mount new procfs on DEST\n" " --dev DEST Mount new dev on DEST\n" " --tmpfs DEST Mount new tmpfs on DEST\n" @@ -1681,6 +1683,15 @@ parse_args_recurse (int *argcp, if (label_create_file (opt_file_label)) die_with_error ("--file-label setup failed"); + argv += 1; + argc -= 1; + } + else if (strcmp (arg, "--apparmor-profile") == 0) + { + if (argc < 2) + die ("--apparmor-profile takes an argument"); + opt_apparmor_profile = argv[1]; + argv += 1; argc -= 1; } @@ -2245,10 +2256,6 @@ main (int argc, /* Get the (optional) privileges we need */ acquire_privs (); - /* Never gain any more privs during exec */ - if (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) - die_with_error ("prctl(PR_SET_NO_NEW_PRIVS) failed"); - /* The initial code is run with high permissions (i.e. CAP_SYS_ADMIN), so take lots of care. */ @@ -2836,6 +2843,13 @@ main (int argc, if (label_exec (opt_exec_label) == -1) die_with_error ("label_exec %s", argv[0]); + if (apparmor_change_profile (opt_apparmor_profile) == -1) + die_with_error ("apparmor_change_profile %s", opt_apparmor_profile); + + /* Never gain any more privs during exec */ + if (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) + die_with_error ("prctl(PR_SET_NO_NEW_PRIVS) failed"); + __debug__ (("forking for child\n")); if (!opt_as_pid_1 && (opt_unshare_pid || lock_files != NULL || opt_sync_fd != -1)) diff --git a/bwrap.xml b/bwrap.xml index e0e9c697..b77b6b58 100644 --- a/bwrap.xml +++ b/bwrap.xml @@ -283,6 +283,13 @@ the SELinux context for the sandbox content. + + + + AppArmor Profile from the sandbox. On an AppArmor system you can specify the + profile for the sandbox process(s). Requires writable procfs. + + diff --git a/utils.c b/utils.c index a99a8650..f1da18e3 100644 --- a/utils.c +++ b/utils.c @@ -824,3 +824,16 @@ label_exec (const char *exec_label) #endif return 0; } + +int apparmor_change_profile (const char *profile) +{ + cleanup_free char *data = NULL; + + if (!profile) + return 0; + data = strconcat ("changeprofile ", profile); + if (write_file_at (-1, "/proc/self/attr/apparmor/current", data) == -1) + return -1; + + return 0; +} diff --git a/utils.h b/utils.h index 8c4db619..a462cadb 100644 --- a/utils.h +++ b/utils.h @@ -122,6 +122,7 @@ char *label_mount (const char *opt, const char *mount_label); int label_exec (const char *exec_label); int label_create_file (const char *file_label); +int apparmor_change_profile (const char *profile); static inline void cleanup_freep (void *p)