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)