diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-06-05 22:46:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-06 11:29:11 -0700 |
commit | d1ee2971f5bd8a16bc5ecfe1b00e14b4fe407c4f (patch) | |
tree | 733c51b66dda47216ca1526fdd85004206fd0ec8 | |
parent | 7db9cfd380205f6b50afdc3bc3619f876a5eaf0d (diff) | |
download | op-kernel-dev-d1ee2971f5bd8a16bc5ecfe1b00e14b4fe407c4f.zip op-kernel-dev-d1ee2971f5bd8a16bc5ecfe1b00e14b4fe407c4f.tar.gz |
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 f9941a7..baf3488 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -106,7 +106,7 @@ free_and_exit: static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, struct dev_whitelist_item *wh) { - struct dev_whitelist_item *whcopy; + struct dev_whitelist_item *whcopy, *walk; whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); if (!whcopy) @@ -114,7 +114,21 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, memcpy(whcopy, wh, sizeof(*whcopy)); spin_lock(&dev_cgroup->lock); - list_add_tail(&whcopy->list, &dev_cgroup->whitelist); + list_for_each_entry(walk, &dev_cgroup->whitelist, list) { + if (walk->type != wh->type) + continue; + if (walk->major != wh->major) + continue; + if (walk->minor != wh->minor) + continue; + + walk->access |= wh->access; + kfree(whcopy); + whcopy = NULL; + } + + if (whcopy != NULL) + list_add_tail(&whcopy->list, &dev_cgroup->whitelist); spin_unlock(&dev_cgroup->lock); return 0; } |