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.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: