aboutsummaryrefslogtreecommitdiffstats
path: root/security/device_cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/device_cgroup.c')
-rw-r--r--security/device_cgroup.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 3aacd0fe7179..5fda7df19723 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -11,6 +11,7 @@
11#include <linux/uaccess.h> 11#include <linux/uaccess.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/rcupdate.h> 13#include <linux/rcupdate.h>
14#include <linux/mutex.h>
14 15
15#define ACC_MKNOD 1 16#define ACC_MKNOD 1
16#define ACC_READ 2 17#define ACC_READ 2
@@ -21,9 +22,11 @@
21#define DEV_CHAR 2 22#define DEV_CHAR 2
22#define DEV_ALL 4 /* this represents all devices */ 23#define DEV_ALL 4 /* this represents all devices */
23 24
25static DEFINE_MUTEX(devcgroup_mutex);
26
24/* 27/*
25 * whitelist locking rules: 28 * whitelist locking rules:
26 * hold cgroup_lock() for update/read. 29 * hold devcgroup_mutex for update/read.
27 * hold rcu_read_lock() for read. 30 * hold rcu_read_lock() for read.
28 */ 31 */
29 32
@@ -67,7 +70,7 @@ static int devcgroup_can_attach(struct cgroup_subsys *ss,
67} 70}
68 71
69/* 72/*
70 * called under cgroup_lock() 73 * called under devcgroup_mutex
71 */ 74 */
72static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) 75static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
73{ 76{
@@ -92,7 +95,7 @@ free_and_exit:
92 95
93/* Stupid prototype - don't bother combining existing entries */ 96/* Stupid prototype - don't bother combining existing entries */
94/* 97/*
95 * called under cgroup_lock() 98 * called under devcgroup_mutex
96 */ 99 */
97static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, 100static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
98 struct dev_whitelist_item *wh) 101 struct dev_whitelist_item *wh)
@@ -130,7 +133,7 @@ static void whitelist_item_free(struct rcu_head *rcu)
130} 133}
131 134
132/* 135/*
133 * called under cgroup_lock() 136 * called under devcgroup_mutex
134 */ 137 */
135static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup, 138static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup,
136 struct dev_whitelist_item *wh) 139 struct dev_whitelist_item *wh)
@@ -185,8 +188,10 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
185 list_add(&wh->list, &dev_cgroup->whitelist); 188 list_add(&wh->list, &dev_cgroup->whitelist);
186 } else { 189 } else {
187 parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); 190 parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup);
191 mutex_lock(&devcgroup_mutex);
188 ret = dev_whitelist_copy(&dev_cgroup->whitelist, 192 ret = dev_whitelist_copy(&dev_cgroup->whitelist,
189 &parent_dev_cgroup->whitelist); 193 &parent_dev_cgroup->whitelist);
194 mutex_unlock(&devcgroup_mutex);
190 if (ret) { 195 if (ret) {
191 kfree(dev_cgroup); 196 kfree(dev_cgroup);
192 return ERR_PTR(ret); 197 return ERR_PTR(ret);
@@ -273,7 +278,7 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft,
273 * does the access granted to dev_cgroup c contain the access 278 * does the access granted to dev_cgroup c contain the access
274 * requested in whitelist item refwh. 279 * requested in whitelist item refwh.
275 * return 1 if yes, 0 if no. 280 * return 1 if yes, 0 if no.
276 * call with c->lock held 281 * call with devcgroup_mutex held
277 */ 282 */
278static int may_access_whitelist(struct dev_cgroup *c, 283static int may_access_whitelist(struct dev_cgroup *c,
279 struct dev_whitelist_item *refwh) 284 struct dev_whitelist_item *refwh)
@@ -426,11 +431,11 @@ static int devcgroup_access_write(struct cgroup *cgrp, struct cftype *cft,
426 const char *buffer) 431 const char *buffer)
427{ 432{
428 int retval; 433 int retval;
429 if (!cgroup_lock_live_group(cgrp)) 434
430 return -ENODEV; 435 mutex_lock(&devcgroup_mutex);
431 retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp), 436 retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp),
432 cft->private, buffer); 437 cft->private, buffer);
433 cgroup_unlock(); 438 mutex_unlock(&devcgroup_mutex);
434 return retval; 439 return retval;
435} 440}
436 441