diff options
Diffstat (limited to 'security/device_cgroup.c')
| -rw-r--r-- | security/device_cgroup.c | 20 | 
1 files changed, 16 insertions, 4 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index b08d20c66c2..19ecc8de9e6 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -82,6 +82,8 @@ static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig)  {  	struct dev_exception_item *ex, *tmp, *new; +	lockdep_assert_held(&devcgroup_mutex); +  	list_for_each_entry(ex, orig, list) {  		new = kmemdup(ex, sizeof(*ex), GFP_KERNEL);  		if (!new) @@ -107,6 +109,8 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,  {  	struct dev_exception_item *excopy, *walk; +	lockdep_assert_held(&devcgroup_mutex); +  	excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL);  	if (!excopy)  		return -ENOMEM; @@ -137,6 +141,8 @@ static void dev_exception_rm(struct dev_cgroup *dev_cgroup,  {  	struct dev_exception_item *walk, *tmp; +	lockdep_assert_held(&devcgroup_mutex); +  	list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) {  		if (walk->type != ex->type)  			continue; @@ -163,6 +169,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)  {  	struct dev_exception_item *ex, *tmp; +	lockdep_assert_held(&devcgroup_mutex); +  	list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {  		list_del_rcu(&ex->list);  		kfree_rcu(ex, rcu); @@ -172,7 +180,7 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)  /*   * called from kernel/cgroup.c with cgroup_lock() held.   */ -static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup) +static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup)  {  	struct dev_cgroup *dev_cgroup, *parent_dev_cgroup;  	struct cgroup *parent_cgroup; @@ -202,7 +210,7 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup)  	return &dev_cgroup->css;  } -static void devcgroup_destroy(struct cgroup *cgroup) +static void devcgroup_css_free(struct cgroup *cgroup)  {  	struct dev_cgroup *dev_cgroup; @@ -298,6 +306,10 @@ static int may_access(struct dev_cgroup *dev_cgroup,  	struct dev_exception_item *ex;  	bool match = false; +	rcu_lockdep_assert(rcu_read_lock_held() || +			   lockdep_is_held(&devcgroup_mutex), +			   "device_cgroup::may_access() called without proper synchronization"); +  	list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {  		if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))  			continue; @@ -552,8 +564,8 @@ static struct cftype dev_cgroup_files[] = {  struct cgroup_subsys devices_subsys = {  	.name = "devices",  	.can_attach = devcgroup_can_attach, -	.create = devcgroup_create, -	.destroy = devcgroup_destroy, +	.css_alloc = devcgroup_css_alloc, +	.css_free = devcgroup_css_free,  	.subsys_id = devices_subsys_id,  	.base_cftypes = dev_cgroup_files,  |