aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-07-19 02:04:47 -0400
committerJohn Johansen <john.johansen@canonical.com>2017-09-22 16:00:57 -0400
commit2ea3ffb7782a84da33a8382f13ebd016da50079b (patch)
tree40ad5dff6b1b6750aa36daf7fbecb7430ca9a3c0 /security
parentcd1dbf76b23d5ab2cba5e657fe20b1e236a408cc (diff)
apparmor: add mount mediation
Add basic mount mediation. That allows controlling based on basic mount parameters. It does not include special mount parameters for apparmor, super block labeling, or any triggers for apparmor namespace parameter modifications on pivot root. default userspace policy rules have the form of MOUNT RULE = ( MOUNT | REMOUNT | UMOUNT ) MOUNT = [ QUALIFIERS ] 'mount' [ MOUNT CONDITIONS ] [ SOURCE FILEGLOB ] [ '->' MOUNTPOINT FILEGLOB ] REMOUNT = [ QUALIFIERS ] 'remount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB UMOUNT = [ QUALIFIERS ] 'umount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB MOUNT CONDITIONS = [ ( 'fstype' | 'vfstype' ) ( '=' | 'in' ) MOUNT FSTYPE EXPRESSION ] [ 'options' ( '=' | 'in' ) MOUNT FLAGS EXPRESSION ] MOUNT FSTYPE EXPRESSION = ( MOUNT FSTYPE LIST | MOUNT EXPRESSION ) MOUNT FSTYPE LIST = Comma separated list of valid filesystem and virtual filesystem types (eg ext4, debugfs, etc) MOUNT FLAGS EXPRESSION = ( MOUNT FLAGS LIST | MOUNT EXPRESSION ) MOUNT FLAGS LIST = Comma separated list of MOUNT FLAGS. MOUNT FLAGS = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec' | 'exec' | 'sync' | 'async' | 'remount' | 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' | 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' | 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' | 'unbindable' | 'runbindable' | 'private' | 'rprivate' | 'slave' | 'rslave' | 'shared' | 'rshared' | 'relatime' | 'norelatime' | 'iversion' | 'noiversion' | 'strictatime' | 'nouser' | 'user' ) MOUNT EXPRESSION = ( ALPHANUMERIC | AARE ) ... PIVOT ROOT RULE = [ QUALIFIERS ] pivot_root [ oldroot=OLD PUT FILEGLOB ] [ NEW ROOT FILEGLOB ] SOURCE FILEGLOB = FILEGLOB MOUNTPOINT FILEGLOB = FILEGLOB eg. mount, mount /dev/foo, mount options=ro /dev/foo -> /mnt/, mount options in (ro,atime) /dev/foo -> /mnt/, mount options=ro options=atime, Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/Makefile2
-rw-r--r--security/apparmor/apparmorfs.c8
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/include/apparmor.h1
-rw-r--r--security/apparmor/include/audit.h11
-rw-r--r--security/apparmor/include/domain.h5
-rw-r--r--security/apparmor/include/mount.h54
-rw-r--r--security/apparmor/lsm.c64
-rw-r--r--security/apparmor/mount.c696
9 files changed, 841 insertions, 4 deletions
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index a16b195274de..81a34426d024 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
4 4
5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ 5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ 6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
7 resource.o secid.o file.o policy_ns.o label.o 7 resource.o secid.o file.o policy_ns.o label.o mount.o
8apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o 8apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
9 9
10clean-files := capability_names.h rlim_names.h 10clean-files := capability_names.h rlim_names.h
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index a5f9e1aa51f7..8fa6c898c44b 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -2159,9 +2159,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
2159 { } 2159 { }
2160}; 2160};
2161 2161
2162static struct aa_sfs_entry aa_sfs_entry_mount[] = {
2163 AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
2164 { }
2165};
2166
2162static struct aa_sfs_entry aa_sfs_entry_ns[] = { 2167static struct aa_sfs_entry aa_sfs_entry_ns[] = {
2163 AA_SFS_FILE_BOOLEAN("profile", 1), 2168 AA_SFS_FILE_BOOLEAN("profile", 1),
2164 AA_SFS_FILE_BOOLEAN("pivot_root", 1), 2169 AA_SFS_FILE_BOOLEAN("pivot_root", 0),
2165 { } 2170 { }
2166}; 2171};
2167 2172
@@ -2180,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
2180 AA_SFS_DIR("policy", aa_sfs_entry_policy), 2185 AA_SFS_DIR("policy", aa_sfs_entry_policy),
2181 AA_SFS_DIR("domain", aa_sfs_entry_domain), 2186 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2182 AA_SFS_DIR("file", aa_sfs_entry_file), 2187 AA_SFS_DIR("file", aa_sfs_entry_file),
2188 AA_SFS_DIR("mount", aa_sfs_entry_mount),
2183 AA_SFS_DIR("namespaces", aa_sfs_entry_ns), 2189 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
2184 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), 2190 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2185 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit), 2191 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index d0594446ae3f..ffc8c75a6785 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name)
374 * 374 *
375 * Returns: refcounted label, or NULL on failure (MAYBE NULL) 375 * Returns: refcounted label, or NULL on failure (MAYBE NULL)
376 */ 376 */
377static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, 377struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
378 const char **name) 378 const char **name)
379{ 379{
380 struct aa_label *label = NULL; 380 struct aa_label *label = NULL;
381 u32 xtype = xindex & AA_X_TYPE_MASK; 381 u32 xtype = xindex & AA_X_TYPE_MASK;
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 962a20a75e01..829082c35faa 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -27,6 +27,7 @@
27#define AA_CLASS_NET 4 27#define AA_CLASS_NET 4
28#define AA_CLASS_RLIMITS 5 28#define AA_CLASS_RLIMITS 5
29#define AA_CLASS_DOMAIN 6 29#define AA_CLASS_DOMAIN 6
30#define AA_CLASS_MOUNT 7
30#define AA_CLASS_PTRACE 9 31#define AA_CLASS_PTRACE 9
31#define AA_CLASS_SIGNAL 10 32#define AA_CLASS_SIGNAL 10
32#define AA_CLASS_LABEL 16 33#define AA_CLASS_LABEL 16
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index d9a156ae11b9..c3fe1c5ef3bc 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -71,6 +71,10 @@ enum audit_type {
71#define OP_FMPROT "file_mprotect" 71#define OP_FMPROT "file_mprotect"
72#define OP_INHERIT "file_inherit" 72#define OP_INHERIT "file_inherit"
73 73
74#define OP_PIVOTROOT "pivotroot"
75#define OP_MOUNT "mount"
76#define OP_UMOUNT "umount"
77
74#define OP_CREATE "create" 78#define OP_CREATE "create"
75#define OP_POST_CREATE "post_create" 79#define OP_POST_CREATE "post_create"
76#define OP_BIND "bind" 80#define OP_BIND "bind"
@@ -132,6 +136,13 @@ struct apparmor_audit_data {
132 int rlim; 136 int rlim;
133 unsigned long max; 137 unsigned long max;
134 } rlim; 138 } rlim;
139 struct {
140 const char *src_name;
141 const char *type;
142 const char *trans;
143 const char *data;
144 unsigned long flags;
145 } mnt;
135 }; 146 };
136}; 147};
137 148
diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
index bab5810b6e9a..db27403346c5 100644
--- a/security/apparmor/include/domain.h
+++ b/security/apparmor/include/domain.h
@@ -15,6 +15,8 @@
15#include <linux/binfmts.h> 15#include <linux/binfmts.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18#include "label.h"
19
18#ifndef __AA_DOMAIN_H 20#ifndef __AA_DOMAIN_H
19#define __AA_DOMAIN_H 21#define __AA_DOMAIN_H
20 22
@@ -29,6 +31,9 @@ struct aa_domain {
29#define AA_CHANGE_ONEXEC 4 31#define AA_CHANGE_ONEXEC 4
30#define AA_CHANGE_STACK 8 32#define AA_CHANGE_STACK 8
31 33
34struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
35 const char **name);
36
32int apparmor_bprm_set_creds(struct linux_binprm *bprm); 37int apparmor_bprm_set_creds(struct linux_binprm *bprm);
33int apparmor_bprm_secureexec(struct linux_binprm *bprm); 38int apparmor_bprm_secureexec(struct linux_binprm *bprm);
34 39
diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
new file mode 100644
index 000000000000..25d6067fa6ef
--- /dev/null
+++ b/security/apparmor/include/mount.h
@@ -0,0 +1,54 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor file mediation function definitions.
5 *
6 * Copyright 2017 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the
11 * License.
12 */
13
14#ifndef __AA_MOUNT_H
15#define __AA_MOUNT_H
16
17#include <linux/fs.h>
18#include <linux/path.h>
19
20#include "domain.h"
21#include "policy.h"
22
23/* mount perms */
24#define AA_MAY_PIVOTROOT 0x01
25#define AA_MAY_MOUNT 0x02
26#define AA_MAY_UMOUNT 0x04
27#define AA_AUDIT_DATA 0x40
28#define AA_MNT_CONT_MATCH 0x40
29
30#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
31
32int aa_remount(struct aa_label *label, const struct path *path,
33 unsigned long flags, void *data);
34
35int aa_bind_mount(struct aa_label *label, const struct path *path,
36 const char *old_name, unsigned long flags);
37
38
39int aa_mount_change_type(struct aa_label *label, const struct path *path,
40 unsigned long flags);
41
42int aa_move_mount(struct aa_label *label, const struct path *path,
43 const char *old_name);
44
45int aa_new_mount(struct aa_label *label, const char *dev_name,
46 const struct path *path, const char *type, unsigned long flags,
47 void *data);
48
49int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
50
51int aa_pivotroot(struct aa_label *label, const struct path *old_path,
52