aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-24 06:48:46 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-24 06:48:46 -0400
commit8c82a17e9c924c0e9f13e75e4c2f6bca19a4b516 (patch)
treed535f46a917e14e90deccb29ad00aac016ad18dd /security
parent4ce72a2c063a7fa8e42a9435440ae3364115a58d (diff)
parent57f8f7b60db6f1ed2c6918ab9230c4623a9dbe37 (diff)
Merge commit 'v2.6.28-rc1' into sched/urgent
Diffstat (limited to 'security')
-rw-r--r--security/device_cgroup.c46
-rw-r--r--security/selinux/hooks.c9
2 files changed, 10 insertions, 45 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 46f23971f7e4..5ba78701adc3 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * dev_cgroup.c - device cgroup subsystem 2 * device_cgroup.c - device cgroup subsystem
3 * 3 *
4 * Copyright 2007 IBM Corp 4 * Copyright 2007 IBM Corp
5 */ 5 */
@@ -10,6 +10,7 @@
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/uaccess.h> 11#include <linux/uaccess.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/rcupdate.h>
13 14
14#define ACC_MKNOD 1 15#define ACC_MKNOD 1
15#define ACC_READ 2 16#define ACC_READ 2
@@ -22,18 +23,8 @@
22 23
23/* 24/*
24 * whitelist locking rules: 25 * whitelist locking rules:
25 * cgroup_lock() cannot be taken under dev_cgroup->lock. 26 * hold cgroup_lock() for update/read.
26 * dev_cgroup->lock can be taken with or without cgroup_lock(). 27 * hold rcu_read_lock() for read.
27 *
28 * modifications always require cgroup_lock
29 * modifications to a list which is visible require the
30 * dev_cgroup->lock *and* cgroup_lock()
31 * walking the list requires dev_cgroup->lock or cgroup_lock().
32 *
33 * reasoning: dev_whitelist_copy() needs to kmalloc, so needs
34 * a mutex, which the cgroup_lock() is. Since modifying
35 * a visible list requires both locks, either lock can be
36 * taken for walking the list.
37 */ 28 */
38 29
39struct dev_whitelist_item { 30struct dev_whitelist_item {
@@ -47,7 +38,6 @@ struct dev_whitelist_item {
47struct dev_cgroup { 38struct dev_cgroup {
48 struct cgroup_subsys_state css; 39 struct cgroup_subsys_state css;
49 struct list_head whitelist; 40 struct list_head whitelist;
50 spinlock_t lock;
51}; 41};
52 42
53static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) 43static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
@@ -84,13 +74,9 @@ static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
84 struct dev_whitelist_item *wh, *tmp, *new; 74 struct dev_whitelist_item *wh, *tmp, *new;
85 75
86 list_for_each_entry(wh, orig, list) { 76 list_for_each_entry(wh, orig, list) {
87 new = kmalloc(sizeof(*wh), GFP_KERNEL); 77 new = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
88 if (!new) 78 if (!new)
89 goto free_and_exit; 79 goto free_and_exit;
90 new->major = wh->major;
91 new->minor = wh->minor;
92 new->type = wh->type;
93 new->access = wh->access;
94 list_add_tail(&new->list, dest); 80 list_add_tail(&new->list, dest);
95 } 81 }
96 82
@@ -107,19 +93,16 @@ free_and_exit:
107/* Stupid prototype - don't bother combining existing entries */ 93/* Stupid prototype - don't bother combining existing entries */
108/* 94/*
109 * called under cgroup_lock() 95 * called under cgroup_lock()
110 * since the list is visible to other tasks, we need the spinlock also
111 */ 96 */
112static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, 97static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
113 struct dev_whitelist_item *wh) 98 struct dev_whitelist_item *wh)
114{ 99{
115 struct dev_whitelist_item *whcopy, *walk; 100 struct dev_whitelist_item *whcopy, *walk;
116 101
117 whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); 102 whcopy = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
118 if (!whcopy) 103 if (!whcopy)
119 return -ENOMEM; 104 return -ENOMEM;
120 105
121 memcpy(whcopy, wh, sizeof(*whcopy));
122 spin_lock(&dev_cgroup->lock);
123 list_for_each_entry(walk, &dev_cgroup->whitelist, list) { 106 list_for_each_entry(walk, &dev_cgroup->whitelist, list) {
124 if (walk->type != wh->type) 107 if (walk->type != wh->type)
125 continue; 108 continue;
@@ -135,7 +118,6 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
135 118
136 if (whcopy != NULL) 119 if (whcopy != NULL)
137 list_add_tail_rcu(&whcopy->list, &dev_cgroup->whitelist); 120 list_add_tail_rcu(&whcopy->list, &dev_cgroup->whitelist);
138 spin_unlock(&dev_cgroup->lock);
139 return 0; 121 return 0;
140} 122}
141 123
@@ -149,14 +131,12 @@ static void whitelist_item_free(struct rcu_head *rcu)
149 131
150/* 132/*
151 * called under cgroup_lock() 133 * called under cgroup_lock()
152 * since the list is visible to other tasks, we need the spinlock also
153 */ 134 */
154static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup, 135static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup,
155 struct dev_whitelist_item *wh) 136 struct dev_whitelist_item *wh)
156{ 137{
157 struct dev_whitelist_item *walk, *tmp; 138 struct dev_whitelist_item *walk, *tmp;
158 139
159 spin_lock(&dev_cgroup->lock);
160 list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) { 140 list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) {
161 if (walk->type == DEV_ALL) 141 if (walk->type == DEV_ALL)
162 goto remove; 142 goto remove;
@@ -174,7 +154,6 @@ remove:
174 call_rcu(&walk->rcu, whitelist_item_free); 154 call_rcu(&walk->rcu, whitelist_item_free);
175 } 155 }
176 } 156 }
177 spin_unlock(&dev_cgroup->lock);
178} 157}
179 158
180/* 159/*
@@ -214,7 +193,6 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
214 } 193 }
215 } 194 }
216 195
217 spin_lock_init(&dev_cgroup->lock);
218 return &dev_cgroup->css; 196 return &dev_cgroup->css;
219} 197}
220 198
@@ -330,15 +308,11 @@ static int parent_has_perm(struct dev_cgroup *childcg,
330{ 308{
331 struct cgroup *pcg = childcg->css.cgroup->parent; 309 struct cgroup *pcg = childcg->css.cgroup->parent;
332 struct dev_cgroup *parent; 310 struct dev_cgroup *parent;
333 int ret;
334 311
335 if (!pcg) 312 if (!pcg)
336 return 1; 313 return 1;
337 parent = cgroup_to_devcgroup(pcg); 314 parent = cgroup_to_devcgroup(pcg);
338 spin_lock(&parent->lock); 315 return may_access_whitelist(parent, wh);
339 ret = may_access_whitelist(parent, wh);
340 spin_unlock(&parent->lock);
341 return ret;
342} 316}
343 317
344/* 318/*
@@ -357,17 +331,14 @@ static int parent_has_perm(struct dev_cgroup *childcg,
357static int devcgroup_update_access(struct dev_cgroup *devcgroup, 331static int devcgroup_update_access(struct dev_cgroup *devcgroup,
358 int filetype, const char *buffer) 332 int filetype, const char *buffer)
359{ 333{
360 struct dev_cgroup *cur_devcgroup;
361 const char *b; 334 const char *b;
362 char *endp; 335 char *endp;
363 int retval = 0, count; 336 int count;
364 struct dev_whitelist_item wh; 337 struct dev_whitelist_item wh;
365 338
366 if (!capable(CAP_SYS_ADMIN)) 339 if (!capable(CAP_SYS_ADMIN))
367 return -EPERM; 340 return -EPERM;
368 341
369 cur_devcgroup = task_devcgroup(current);
370
371 memset(&wh, 0, sizeof(wh)); 342 memset(&wh, 0, sizeof(wh));
372 b = buffer; 343 b = buffer;
373 344
@@ -437,7 +408,6 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
437 } 408 }
438 409
439handle: 410handle:
440 retval = 0;
441 switch (filetype) { 411 switch (filetype) {
442 case DEVCG_ALLOW: 412 case DEVCG_ALLOW:
443 if (!parent_has_perm(devcgroup, &wh)) 413 if (!parent_has_perm(devcgroup, &wh))
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 576e51199079..3e3fde7c1d2b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -75,6 +75,7 @@
75#include <linux/string.h> 75#include <linux/string.h>
76#include <linux/selinux.h> 76#include <linux/selinux.h>
77#include <linux/mutex.h> 77#include <linux/mutex.h>
78#include <linux/posix-timers.h>
78 79
79#include "avc.h" 80#include "avc.h"
80#include "objsec.h" 81#include "objsec.h"
@@ -2322,13 +2323,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2322 initrlim = init_task.signal->rlim+i; 2323 initrlim = init_task.signal->rlim+i;
2323 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); 2324 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2324 } 2325 }
2325 if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { 2326 update_rlimit_cpu(rlim->rlim_cur);
2326 /*
2327 * This will cause RLIMIT_CPU calculations
2328 * to be refigured.
2329 */
2330 current->it_prof_expires = jiffies_to_cputime(1);
2331 }
2332 } 2327 }
2333 2328
2334 /* Wake up the parent if it is waiting so that it can 2329 /* Wake up the parent if it is waiting so that it can