diff options
Diffstat (limited to 'security/device_cgroup.c')
-rw-r--r-- | security/device_cgroup.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 7d0f8f7431ff..a9f8c63a96d1 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -5,6 +5,7 @@ * Copyright 2007 IBM Corp */ +#include <linux/bpf-cgroup.h> #include <linux/device_cgroup.h> #include <linux/cgroup.h> #include <linux/ctype.h> @@ -15,6 +16,8 @@ #include <linux/rcupdate.h> #include <linux/mutex.h> +#ifdef CONFIG_CGROUP_DEVICE + static DEFINE_MUTEX(devcgroup_mutex); enum devcg_behavior { @@ -352,7 +355,8 @@ static bool match_exception_partial(struct list_head *exceptions, short type, { struct dev_exception_item *ex; - list_for_each_entry_rcu(ex, exceptions, list) { + list_for_each_entry_rcu(ex, exceptions, list, + lockdep_is_held(&devcgroup_mutex)) { if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK)) continue; if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR)) @@ -792,7 +796,7 @@ struct cgroup_subsys devices_cgrp_subsys = { }; /** - * __devcgroup_check_permission - checks if an inode operation is permitted + * devcgroup_legacy_check_permission - checks if an inode operation is permitted * @dev_cgroup: the dev cgroup to be tested against * @type: device type * @major: device major number @@ -801,7 +805,7 @@ struct cgroup_subsys devices_cgrp_subsys = { * * returns 0 on success, -EPERM case the operation is not permitted */ -static int __devcgroup_check_permission(short type, u32 major, u32 minor, +static int devcgroup_legacy_check_permission(short type, u32 major, u32 minor, short access) { struct dev_cgroup *dev_cgroup; @@ -825,13 +829,24 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor, return 0; } +#endif /* CONFIG_CGROUP_DEVICE */ + +#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) + int devcgroup_check_permission(short type, u32 major, u32 minor, short access) { int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access); if (rc) - return -EPERM; + return rc; + + #ifdef CONFIG_CGROUP_DEVICE + return devcgroup_legacy_check_permission(type, major, minor, access); + + #else /* CONFIG_CGROUP_DEVICE */ + return 0; - return __devcgroup_check_permission(type, major, minor, access); + #endif /* CONFIG_CGROUP_DEVICE */ } EXPORT_SYMBOL(devcgroup_check_permission); +#endif /* defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) */ |