diff options
Diffstat (limited to 'security/device_cgroup.c')
| -rw-r--r-- | security/device_cgroup.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 4ea583689eec..baf348834b66 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
| @@ -49,10 +49,14 @@ struct dev_cgroup { | |||
| 49 | spinlock_t lock; | 49 | spinlock_t lock; |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) | ||
| 53 | { | ||
| 54 | return container_of(s, struct dev_cgroup, css); | ||
| 55 | } | ||
| 56 | |||
| 52 | static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup) | 57 | static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup) |
| 53 | { | 58 | { |
| 54 | return container_of(cgroup_subsys_state(cgroup, devices_subsys_id), | 59 | return css_to_devcgroup(cgroup_subsys_state(cgroup, devices_subsys_id)); |
| 55 | struct dev_cgroup, css); | ||
| 56 | } | 60 | } |
| 57 | 61 | ||
| 58 | struct cgroup_subsys devices_subsys; | 62 | struct cgroup_subsys devices_subsys; |
| @@ -102,7 +106,7 @@ free_and_exit: | |||
| 102 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | 106 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, |
| 103 | struct dev_whitelist_item *wh) | 107 | struct dev_whitelist_item *wh) |
| 104 | { | 108 | { |
| 105 | struct dev_whitelist_item *whcopy; | 109 | struct dev_whitelist_item *whcopy, *walk; |
| 106 | 110 | ||
| 107 | whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); | 111 | whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); |
| 108 | if (!whcopy) | 112 | if (!whcopy) |
| @@ -110,7 +114,21 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | |||
| 110 | 114 | ||
| 111 | memcpy(whcopy, wh, sizeof(*whcopy)); | 115 | memcpy(whcopy, wh, sizeof(*whcopy)); |
| 112 | spin_lock(&dev_cgroup->lock); | 116 | spin_lock(&dev_cgroup->lock); |
| 113 | list_add_tail(&whcopy->list, &dev_cgroup->whitelist); | 117 | list_for_each_entry(walk, &dev_cgroup->whitelist, list) { |
| 118 | if (walk->type != wh->type) | ||
| 119 | continue; | ||
| 120 | if (walk->major != wh->major) | ||
| 121 | continue; | ||
| 122 | if (walk->minor != wh->minor) | ||
| 123 | continue; | ||
| 124 | |||
| 125 | walk->access |= wh->access; | ||
| 126 | kfree(whcopy); | ||
| 127 | whcopy = NULL; | ||
| 128 | } | ||
| 129 | |||
| 130 | if (whcopy != NULL) | ||
| 131 | list_add_tail(&whcopy->list, &dev_cgroup->whitelist); | ||
| 114 | spin_unlock(&dev_cgroup->lock); | 132 | spin_unlock(&dev_cgroup->lock); |
| 115 | return 0; | 133 | return 0; |
| 116 | } | 134 | } |
| @@ -502,7 +520,6 @@ struct cgroup_subsys devices_subsys = { | |||
| 502 | 520 | ||
| 503 | int devcgroup_inode_permission(struct inode *inode, int mask) | 521 | int devcgroup_inode_permission(struct inode *inode, int mask) |
| 504 | { | 522 | { |
| 505 | struct cgroup *cgroup; | ||
| 506 | struct dev_cgroup *dev_cgroup; | 523 | struct dev_cgroup *dev_cgroup; |
| 507 | struct dev_whitelist_item *wh; | 524 | struct dev_whitelist_item *wh; |
| 508 | 525 | ||
| @@ -511,8 +528,8 @@ int devcgroup_inode_permission(struct inode *inode, int mask) | |||
| 511 | return 0; | 528 | return 0; |
| 512 | if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode)) | 529 | if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode)) |
| 513 | return 0; | 530 | return 0; |
| 514 | cgroup = task_cgroup(current, devices_subsys.subsys_id); | 531 | dev_cgroup = css_to_devcgroup(task_subsys_state(current, |
| 515 | dev_cgroup = cgroup_to_devcgroup(cgroup); | 532 | devices_subsys_id)); |
| 516 | if (!dev_cgroup) | 533 | if (!dev_cgroup) |
| 517 | return 0; | 534 | return 0; |
| 518 | 535 | ||
| @@ -543,12 +560,11 @@ acc_check: | |||
| 543 | 560 | ||
| 544 | int devcgroup_inode_mknod(int mode, dev_t dev) | 561 | int devcgroup_inode_mknod(int mode, dev_t dev) |
| 545 | { | 562 | { |
| 546 | struct cgroup *cgroup; | ||
| 547 | struct dev_cgroup *dev_cgroup; | 563 | struct dev_cgroup *dev_cgroup; |
| 548 | struct dev_whitelist_item *wh; | 564 | struct dev_whitelist_item *wh; |
| 549 | 565 | ||
| 550 | cgroup = task_cgroup(current, devices_subsys.subsys_id); | 566 | dev_cgroup = css_to_devcgroup(task_subsys_state(current, |
| 551 | dev_cgroup = cgroup_to_devcgroup(cgroup); | 567 | devices_subsys_id)); |
| 552 | if (!dev_cgroup) | 568 | if (!dev_cgroup) |
| 553 | return 0; | 569 | return 0; |
| 554 | 570 | ||
