aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-06 12:16:53 -0500
committerTejun Heo <tj@kernel.org>2012-11-06 15:28:04 -0500
commit4b1c7840b7d01b14a1a00fa0e61b761d4391ba67 (patch)
tree1e93e0a8a0bb6fb2f5934a58a6eb32b3077b18b8 /security
parent5b805f2a7675634fbdf9ac1c9b2256905ab2ea68 (diff)
device_cgroup: add lockdep asserts
device_cgroup uses RCU safe ->exceptions list which is write-protected by devcgroup_mutex and has had some issues using locking correctly. Add lockdep asserts to utility functions so that future errors can be easily detected. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> Cc: Aristeu Rozanski <aris@redhat.com> Cc: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'security')
-rw-r--r--security/device_cgroup.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index b08d20c66c2e..78a16f5b7275 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)
82{ 82{
83 struct dev_exception_item *ex, *tmp, *new; 83 struct dev_exception_item *ex, *tmp, *new;
84 84
85 lockdep_assert_held(&devcgroup_mutex);
86
85 list_for_each_entry(ex, orig, list) { 87 list_for_each_entry(ex, orig, list) {
86 new = kmemdup(ex, sizeof(*ex), GFP_KERNEL); 88 new = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
87 if (!new) 89 if (!new)
@@ -107,6 +109,8 @@ static int dev_exception_add(struct dev_cgroup *dev_cgroup,
107{ 109{
108 struct dev_exception_item *excopy, *walk; 110 struct dev_exception_item *excopy, *walk;
109 111
112 lockdep_assert_held(&devcgroup_mutex);
113
110 excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL); 114 excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL);
111 if (!excopy) 115 if (!excopy)
112 return -ENOMEM; 116 return -ENOMEM;
@@ -137,6 +141,8 @@ static void dev_exception_rm(struct dev_cgroup *dev_cgroup,
137{ 141{
138 struct dev_exception_item *walk, *tmp; 142 struct dev_exception_item *walk, *tmp;
139 143
144 lockdep_assert_held(&devcgroup_mutex);
145
140 list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) { 146 list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) {
141 if (walk->type != ex->type) 147 if (walk->type != ex->type)
142 continue; 148 continue;
@@ -163,6 +169,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup)
163{ 169{
164 struct dev_exception_item *ex, *tmp; 170 struct dev_exception_item *ex, *tmp;
165 171
172 lockdep_assert_held(&devcgroup_mutex);
173
166 list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { 174 list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) {
167 list_del_rcu(&ex->list); 175 list_del_rcu(&ex->list);
168 kfree_rcu(ex, rcu); 176 kfree_rcu(ex, rcu);
@@ -298,6 +306,10 @@ static int may_access(struct dev_cgroup *dev_cgroup,
298 struct dev_exception_item *ex; 306 struct dev_exception_item *ex;
299 bool match = false; 307 bool match = false;
300 308
309 rcu_lockdep_assert(rcu_read_lock_held() ||
310 lockdep_is_held(&devcgroup_mutex),
311 "device_cgroup::may_access() called without proper synchronization");
312
301 list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { 313 list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
302 if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) 314 if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
303 continue; 315 continue;