aboutsummaryrefslogtreecommitdiffstats
path: root/security/device_cgroup.c
diff options
context:
space:
mode:
authorAristeu Rozanski <aris@redhat.com>2012-10-25 16:37:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-25 17:37:52 -0400
commit4cef7299b4786879a3e113e84084a72b24590c5b (patch)
tree31efb5e00be1c1e5cc266046c783c7569e495ede /security/device_cgroup.c
parent26fd8405dd470cb8b54cb96859b7dd437e5e1391 (diff)
device_cgroup: add proper checking when changing default behavior
Before changing a group's default behavior to ALLOW, we must check if its parent's behavior is also ALLOW. Signed-off-by: Aristeu Rozanski <aris@redhat.com> Cc: Tejun Heo <tj@kernel.org> Cc: Li Zefan <lizefan@huawei.com> Cc: James Morris <jmorris@namei.org> Cc: Pavel Emelyanov <xemul@openvz.org> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Cc: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/device_cgroup.c')
-rw-r--r--security/device_cgroup.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 4fbae8d0b36..842c254396d 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -344,6 +344,17 @@ static int parent_has_perm(struct dev_cgroup *childcg,
344 return may_access(parent, ex); 344 return may_access(parent, ex);
345} 345}
346 346
347/**
348 * may_allow_all - checks if it's possible to change the behavior to
349 * allow based on parent's rules.
350 * @parent: device cgroup's parent
351 * returns: != 0 in case it's allowed, 0 otherwise
352 */
353static inline int may_allow_all(struct dev_cgroup *parent)
354{
355 return parent->behavior == DEVCG_DEFAULT_ALLOW;
356}
357
347/* 358/*
348 * Modify the exception list using allow/deny rules. 359 * Modify the exception list using allow/deny rules.
349 * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD 360 * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD
@@ -364,6 +375,8 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
364 char temp[12]; /* 11 + 1 characters needed for a u32 */ 375 char temp[12]; /* 11 + 1 characters needed for a u32 */
365 int count, rc; 376 int count, rc;
366 struct dev_exception_item ex; 377 struct dev_exception_item ex;
378 struct cgroup *p = devcgroup->css.cgroup;
379 struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent);
367 380
368 if (!capable(CAP_SYS_ADMIN)) 381 if (!capable(CAP_SYS_ADMIN))
369 return -EPERM; 382 return -EPERM;
@@ -375,9 +388,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
375 case 'a': 388 case 'a':
376 switch (filetype) { 389 switch (filetype) {
377 case DEVCG_ALLOW: 390 case DEVCG_ALLOW:
378 if (!parent_has_perm(devcgroup, &ex)) 391 if (!may_allow_all(parent))
379 return -EPERM; 392 return -EPERM;
380 dev_exception_clean(devcgroup); 393 dev_exception_clean(devcgroup);
394 rc = dev_exceptions_copy(&devcgroup->exceptions,
395 &parent->exceptions);
396 if (rc)
397 return rc;
381 devcgroup->behavior = DEVCG_DEFAULT_ALLOW; 398 devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
382 break; 399 break;
383 case DEVCG_DENY: 400 case DEVCG_DENY: