[apparmor] [PATCH 16/16] AppArmor: Add mediation of chroot

John Johansen john.johansen at canonical.com
Wed Feb 22 17:10:41 UTC 2012


Add support for chroot rules, which allow a profile to specify where a
chroot can be made.

  chroot /tmp/example,

Signed-off-by: John Johansen <john.johansen at canonical.com>
---
 security/apparmor/apparmorfs.c       |    1 +
 security/apparmor/audit.c            |    1 +
 security/apparmor/include/apparmor.h |    3 +-
 security/apparmor/include/audit.h    |    1 +
 security/apparmor/include/mount.h    |    4 +++
 security/apparmor/lsm.c              |   13 ++++++++++
 security/apparmor/mount.c            |   42 ++++++++++++++++++++++++++++++++++
 7 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index d30aa11..32c1394 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -437,6 +437,7 @@ static struct aa_fs_entry aa_fs_entry_mount[] = {
 static struct aa_fs_entry aa_fs_entry_namespaces[] = {
 	AA_FS_FILE_BOOLEAN("profile",		1),
 	AA_FS_FILE_BOOLEAN("pivot_root",	1),
+	AA_FS_FILE_BOOLEAN("chroot",		1),
 };
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 64e9442..4c80d4f 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -47,6 +47,7 @@ const char *op_table[] = {
 	"pivotroot",
 	"mount",
 	"umount",
+	"chroot",
 
 	"create",
 	"post_create",
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index d615726..5f4b32e 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -30,8 +30,9 @@
 #define AA_CLASS_RLIMITS	5
 #define AA_CLASS_DOMAIN		6
 #define AA_CLASS_MOUNT		7
+#define AA_CLASS_CHROOT		8
 
-#define AA_CLASS_LAST		AA_CLASS_MOUNT
+#define AA_CLASS_LAST		AA_CLASS_CHROOT
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 0e8689d..693f37f 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -76,6 +76,7 @@ enum aa_ops {
 	OP_PIVOTROOT,
 	OP_MOUNT,
 	OP_UMOUNT,
+	OP_CHROOT,
 
 	OP_CREATE,
 	OP_POST_CREATE,
diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
index 6f936bc..a1c5026 100644
--- a/security/apparmor/include/mount.h
+++ b/security/apparmor/include/mount.h
@@ -27,6 +27,8 @@
 
 #define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
 
+/* chroot permissions */
+#define AA_MAY_CHROOT		0x01
 
 int aa_remount(struct aa_profile *profile, struct path *path,
 	       unsigned long flags, void *data);
@@ -50,4 +52,6 @@ int aa_umount(struct aa_profile *profile, struct vfsmount *mnt, int flags);
 int aa_pivotroot(struct aa_profile *profile, struct path *old_path,
 		  struct path *new_path);
 
+int aa_chroot(struct aa_profile *profile, struct path *path);
+
 #endif /* __AA_MOUNT_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3aec025..507ba44 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -544,6 +544,18 @@ static int apparmor_sb_mount(char *dev_name, struct path *path, char *type,
 	return error;
 }
 
+static int apparmor_path_chroot(struct path *path)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	profile = __aa_current_profile();
+	if (!unconfined(profile))
+		error = aa_chroot(profile, path);
+
+	return error;
+}
+
 static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
 {
 	struct aa_profile *profile;
@@ -786,6 +798,7 @@ static struct security_operations apparmor_ops = {
 	.sb_mount =			apparmor_sb_mount,
 	.sb_umount =			apparmor_sb_umount,
 	.sb_pivotroot =			apparmor_sb_pivotroot,
+	.path_chroot =			apparmor_path_chroot,
 
 	.path_link =			apparmor_path_link,
 	.path_unlink =			apparmor_path_unlink,
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 1572bf6..86f6102 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -587,3 +587,45 @@ audit:
 
 	return error;
 }
+
+int aa_chroot(struct aa_profile *profile, struct path *path)
+{
+	struct file_perms perms = { };
+	struct aa_profile *target = NULL;
+	char *buffer = NULL;
+	const char *name, *info = NULL;
+	int error;
+
+	error = aa_path_name(path, profile->path_flags, &buffer, &name, &info);
+	if (error)
+		goto audit;
+
+	if (profile->policy.dfa) {
+		unsigned int state;
+		state = aa_dfa_match(profile->policy.dfa,
+				     profile->policy.start[AA_CLASS_CHROOT],
+				     name);
+		perms = compute_mnt_perms(profile->policy.dfa, state);
+	}
+
+	if (AA_MAY_MOUNT & perms.allow) {
+		if ((perms.xindex & AA_X_TYPE_MASK) == AA_X_TABLE) {
+			target = x_table_lookup(profile, perms.xindex);
+			if (!target)
+				error = -ENOENT;
+			else
+				error = aa_replace_current_profile(target);
+		}
+	} else
+		error = -EACCES;
+
+audit:
+	error = aa_audit_mount(profile, GFP_KERNEL, OP_CHROOT, name,
+			       NULL, NULL, target ? target->base.name : NULL,
+			       0, NULL, AA_MAY_CHROOT, &perms, info, error);
+
+	aa_put_profile(target);
+	kfree(buffer);
+
+	return error;
+}
-- 
1.7.9




More information about the AppArmor mailing list