diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-06-06 01:46:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-06 14:29:11 -0400 |
commit | d1ee2971f5bd8a16bc5ecfe1b00e14b4fe407c4f (patch) | |
tree | 733c51b66dda47216ca1526fdd85004206fd0ec8 | |
parent | 7db9cfd380205f6b50afdc3bc3619f876a5eaf0d (diff) |
devscgroup: make white list more compact in some cases
Consider you added a 'c foo:bar r' permission to some cgroup and then (a
bit later) 'c'foo:bar w' for it. After this you'll see the
c foo:bar r
c foo:bar w
lines in a devices.list file.
Another example - consider you added 10 'c foo:bar r' permissions to some
cgroup (e.g. by mistake). After this you'll see 10 c foo:bar r lines in
a list file.
This is weird. This situation also has one more annoying consequence.
Having many items in a white list makes permissions checking slower, sine
it has to walk a longer list.
The proposal is to merge permissions for items, that correspond to the
same device.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | security/device_cgroup.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index f9941a769738..baf348834b66 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -106,7 +106,7 @@ free_and_exit: | |||
106 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | 106 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, |
107 | struct dev_whitelist_item *wh) | 107 | struct dev_whitelist_item *wh) |
108 | { | 108 | { |
109 | struct dev_whitelist_item *whcopy; | 109 | struct dev_whitelist_item *whcopy, *walk; |
110 | 110 | ||
111 | whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); | 111 | whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); |
112 | if (!whcopy) | 112 | if (!whcopy) |
@@ -114,7 +114,21 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | |||
114 | 114 | ||
115 | memcpy(whcopy, wh, sizeof(*whcopy)); | 115 | memcpy(whcopy, wh, sizeof(*whcopy)); |
116 | spin_lock(&dev_cgroup->lock); | 116 | spin_lock(&dev_cgroup->lock); |
117 | 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); | ||
118 | spin_unlock(&dev_cgroup->lock); | 132 | spin_unlock(&dev_cgroup->lock); |
119 | return 0; | 133 | return 0; |
120 | } | 134 | } |