diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/apparmorfs.c | 13 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 49 | ||||
-rw-r--r-- | security/device_cgroup.c | 2 | ||||
-rw-r--r-- | security/inode.c | 13 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 1 |
5 files changed, 68 insertions, 10 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index fefee040bf79..b9298d2e8165 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -123,17 +123,22 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) return 0; } -static void aafs_evict_inode(struct inode *inode) +static void aafs_i_callback(struct rcu_head *head) { - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); + struct inode *inode = container_of(head, struct inode, i_rcu); if (S_ISLNK(inode->i_mode)) kfree(inode->i_link); + free_inode_nonrcu(inode); +} + +static void aafs_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, aafs_i_callback); } static const struct super_operations aafs_super_ops = { .statfs = simple_statfs, - .evict_inode = aafs_evict_inode, + .destroy_inode = aafs_destroy_inode, .show_path = aafs_show_path, }; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 49d664ddff44..87500bde5a92 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1336,9 +1336,16 @@ module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR); bool aa_g_paranoid_load = true; module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO); +static int param_get_aaintbool(char *buffer, const struct kernel_param *kp); +static int param_set_aaintbool(const char *val, const struct kernel_param *kp); +#define param_check_aaintbool param_check_int +static const struct kernel_param_ops param_ops_aaintbool = { + .set = param_set_aaintbool, + .get = param_get_aaintbool +}; /* Boot time disable flag */ static int apparmor_enabled __lsm_ro_after_init = 1; -module_param_named(enabled, apparmor_enabled, int, 0444); +module_param_named(enabled, apparmor_enabled, aaintbool, 0444); static int __init apparmor_enabled_setup(char *str) { @@ -1413,6 +1420,46 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp) return param_get_uint(buffer, kp); } +/* Can only be set before AppArmor is initialized (i.e. on boot cmdline). */ +static int param_set_aaintbool(const char *val, const struct kernel_param *kp) +{ + struct kernel_param kp_local; + bool value; + int error; + + if (apparmor_initialized) + return -EPERM; + + /* Create local copy, with arg pointing to bool type. */ + value = !!*((int *)kp->arg); + memcpy(&kp_local, kp, sizeof(kp_local)); + kp_local.arg = &value; + + error = param_set_bool(val, &kp_local); + if (!error) + *((int *)kp->arg) = *((bool *)kp_local.arg); + return error; +} + +/* + * To avoid changing /sys/module/apparmor/parameters/enabled from Y/N to + * 1/0, this converts the "int that is actually bool" back to bool for + * display in the /sys filesystem, while keeping it "int" for the LSM + * infrastructure. + */ +static int param_get_aaintbool(char *buffer, const struct kernel_param *kp) +{ + struct kernel_param kp_local; + bool value; + + /* Create local copy, with arg pointing to bool type. */ + value = !!*((int *)kp->arg); + memcpy(&kp_local, kp, sizeof(kp_local)); + kp_local.arg = &value; + + return param_get_bool(buffer, &kp_local); +} + static int param_get_audit(char *buffer, const struct kernel_param *kp) { if (!apparmor_enabled) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index cd97929fac66..dc28914fa72e 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -560,7 +560,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root, devcg->behavior == DEVCG_DEFAULT_ALLOW) { rc = dev_exception_add(devcg, ex); if (rc) - break; + return rc; } else { /* * in the other possible cases: diff --git a/security/inode.c b/security/inode.c index b7772a9b315e..421dd72b5876 100644 --- a/security/inode.c +++ b/security/inode.c @@ -27,17 +27,22 @@ static struct vfsmount *mount; static int mount_count; -static void securityfs_evict_inode(struct inode *inode) +static void securityfs_i_callback(struct rcu_head *head) { - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); + struct inode *inode = container_of(head, struct inode, i_rcu); if (S_ISLNK(inode->i_mode)) kfree(inode->i_link); + free_inode_nonrcu(inode); +} + +static void securityfs_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, securityfs_i_callback); } static const struct super_operations securityfs_super_operations = { .statfs = simple_statfs, - .evict_inode = securityfs_evict_inode, + .destroy_inode = securityfs_destroy_inode, }; static int fill_super(struct super_block *sb, void *data, int silent) diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index bd5fe0d3204a..201f7e588a29 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include <linux/capability.h> +#include <linux/socket.h> #define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map" |