[apparmor] [PATCH 20/20] AppArmor: Add mediation of chroot
John Johansen
john.johansen at canonical.com
Wed Feb 22 17:23:03 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