aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Makefile1
-rw-r--r--security/capability.c1
-rw-r--r--security/commoncap.c109
-rw-r--r--security/device_cgroup.c575
-rw-r--r--security/dummy.c23
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/compat.c3
-rw-r--r--security/keys/internal.h30
-rw-r--r--security/keys/key.c86
-rw-r--r--security/keys/keyctl.c126
-rw-r--r--security/keys/keyring.c54
-rw-r--r--security/keys/proc.c17
-rw-r--r--security/keys/process_keys.c142
-rw-r--r--security/keys/request_key.c50
-rw-r--r--security/keys/request_key_auth.c13
-rw-r--r--security/keys/sysctl.c50
-rw-r--r--security/root_plug.c1
-rw-r--r--security/security.c21
-rw-r--r--security/selinux/hooks.c42
-rw-r--r--security/selinux/include/avc_ss.h9
-rw-r--r--security/selinux/include/netlabel.h2
-rw-r--r--security/selinux/include/objsec.h60
-rw-r--r--security/selinux/include/security.h6
-rw-r--r--security/selinux/netnode.c104
-rw-r--r--security/selinux/netport.c40
-rw-r--r--security/selinux/ss/conditional.h6
-rw-r--r--security/selinux/ss/context.h4
-rw-r--r--security/selinux/ss/hashtab.h6
-rw-r--r--security/selinux/ss/mls.h6
-rw-r--r--security/selinux/ss/mls_types.h4
-rw-r--r--security/selinux/ss/policydb.h10
-rw-r--r--security/selinux/ss/services.c4
-rw-r--r--security/smack/smack_lsm.c15
-rw-r--r--security/smack/smackfs.c4
34 files changed, 1246 insertions, 379 deletions
diff --git a/security/Makefile b/security/Makefile
index 9e8b02525014..7ef1107a7287 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
18obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o 18obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
19obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o 19obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
20obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o 20obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
21obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
diff --git a/security/capability.c b/security/capability.c
index 2c6e06d18fab..38ac54e3aed1 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -44,6 +44,7 @@ static struct security_operations capability_ops = {
44 .task_setioprio = cap_task_setioprio, 44 .task_setioprio = cap_task_setioprio,
45 .task_setnice = cap_task_setnice, 45 .task_setnice = cap_task_setnice,
46 .task_post_setuid = cap_task_post_setuid, 46 .task_post_setuid = cap_task_post_setuid,
47 .task_prctl = cap_task_prctl,
47 .task_reparent_to_init = cap_task_reparent_to_init, 48 .task_reparent_to_init = cap_task_reparent_to_init,
48 49
49 .syslog = cap_syslog, 50 .syslog = cap_syslog,
diff --git a/security/commoncap.c b/security/commoncap.c
index 852905789caf..5edabc7542ae 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -24,11 +24,8 @@
24#include <linux/hugetlb.h> 24#include <linux/hugetlb.h>
25#include <linux/mount.h> 25#include <linux/mount.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27 27#include <linux/prctl.h>
28/* Global security state */ 28#include <linux/securebits.h>
29
30unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
31EXPORT_SYMBOL(securebits);
32 29
33int cap_netlink_send(struct sock *sk, struct sk_buff *skb) 30int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
34{ 31{
@@ -368,7 +365,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
368 365
369 /* AUD: Audit candidate if current->cap_effective is set */ 366 /* AUD: Audit candidate if current->cap_effective is set */
370 367
371 current->keep_capabilities = 0; 368 current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
372} 369}
373 370
374int cap_bprm_secureexec (struct linux_binprm *bprm) 371int cap_bprm_secureexec (struct linux_binprm *bprm)
@@ -386,8 +383,8 @@ int cap_bprm_secureexec (struct linux_binprm *bprm)
386 current->egid != current->gid); 383 current->egid != current->gid);
387} 384}
388 385
389int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, 386int cap_inode_setxattr(struct dentry *dentry, const char *name,
390 size_t size, int flags) 387 const void *value, size_t size, int flags)
391{ 388{
392 if (!strcmp(name, XATTR_NAME_CAPS)) { 389 if (!strcmp(name, XATTR_NAME_CAPS)) {
393 if (!capable(CAP_SETFCAP)) 390 if (!capable(CAP_SETFCAP))
@@ -400,7 +397,7 @@ int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
400 return 0; 397 return 0;
401} 398}
402 399
403int cap_inode_removexattr(struct dentry *dentry, char *name) 400int cap_inode_removexattr(struct dentry *dentry, const char *name)
404{ 401{
405 if (!strcmp(name, XATTR_NAME_CAPS)) { 402 if (!strcmp(name, XATTR_NAME_CAPS)) {
406 if (!capable(CAP_SETFCAP)) 403 if (!capable(CAP_SETFCAP))
@@ -448,7 +445,7 @@ static inline void cap_emulate_setxuid (int old_ruid, int old_euid,
448{ 445{
449 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) && 446 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
450 (current->uid != 0 && current->euid != 0 && current->suid != 0) && 447 (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
451 !current->keep_capabilities) { 448 !issecure(SECURE_KEEP_CAPS)) {
452 cap_clear (current->cap_permitted); 449 cap_clear (current->cap_permitted);
453 cap_clear (current->cap_effective); 450 cap_clear (current->cap_effective);
454 } 451 }
@@ -547,7 +544,7 @@ int cap_task_setnice (struct task_struct *p, int nice)
547 * this task could get inconsistent info. There can be no 544 * this task could get inconsistent info. There can be no
548 * racing writer bc a task can only change its own caps. 545 * racing writer bc a task can only change its own caps.
549 */ 546 */
550long cap_prctl_drop(unsigned long cap) 547static long cap_prctl_drop(unsigned long cap)
551{ 548{
552 if (!capable(CAP_SETPCAP)) 549 if (!capable(CAP_SETPCAP))
553 return -EPERM; 550 return -EPERM;
@@ -556,6 +553,7 @@ long cap_prctl_drop(unsigned long cap)
556 cap_lower(current->cap_bset, cap); 553 cap_lower(current->cap_bset, cap);
557 return 0; 554 return 0;
558} 555}
556
559#else 557#else
560int cap_task_setscheduler (struct task_struct *p, int policy, 558int cap_task_setscheduler (struct task_struct *p, int policy,
561 struct sched_param *lp) 559 struct sched_param *lp)
@@ -572,12 +570,99 @@ int cap_task_setnice (struct task_struct *p, int nice)
572} 570}
573#endif 571#endif
574 572
573int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
574 unsigned long arg4, unsigned long arg5, long *rc_p)
575{
576 long error = 0;
577
578 switch (option) {
579 case PR_CAPBSET_READ:
580 if (!cap_valid(arg2))
581 error = -EINVAL;
582 else
583 error = !!cap_raised(current->cap_bset, arg2);
584 break;
585#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
586 case PR_CAPBSET_DROP:
587 error = cap_prctl_drop(arg2);
588 break;
589
590 /*
591 * The next four prctl's remain to assist with transitioning a
592 * system from legacy UID=0 based privilege (when filesystem
593 * capabilities are not in use) to a system using filesystem
594 * capabilities only - as the POSIX.1e draft intended.
595 *
596 * Note:
597 *
598 * PR_SET_SECUREBITS =
599 * issecure_mask(SECURE_KEEP_CAPS_LOCKED)
600 * | issecure_mask(SECURE_NOROOT)
601 * | issecure_mask(SECURE_NOROOT_LOCKED)
602 * | issecure_mask(SECURE_NO_SETUID_FIXUP)
603 * | issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED)
604 *
605 * will ensure that the current process and all of its
606 * children will be locked into a pure
607 * capability-based-privilege environment.
608 */
609 case PR_SET_SECUREBITS:
610 if ((((current->securebits & SECURE_ALL_LOCKS) >> 1)
611 & (current->securebits ^ arg2)) /*[1]*/
612 || ((current->securebits & SECURE_ALL_LOCKS
613 & ~arg2)) /*[2]*/
614 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
615 || (cap_capable(current, CAP_SETPCAP) != 0)) { /*[4]*/
616 /*
617 * [1] no changing of bits that are locked
618 * [2] no unlocking of locks
619 * [3] no setting of unsupported bits
620 * [4] doing anything requires privilege (go read about
621 * the "sendmail capabilities bug")
622 */
623 error = -EPERM; /* cannot change a locked bit */
624 } else {
625 current->securebits = arg2;
626 }
627 break;
628 case PR_GET_SECUREBITS:
629 error = current->securebits;
630 break;
631
632#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
633
634 case PR_GET_KEEPCAPS:
635 if (issecure(SECURE_KEEP_CAPS))
636 error = 1;
637 break;
638 case PR_SET_KEEPCAPS:
639 if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */
640 error = -EINVAL;
641 else if (issecure(SECURE_KEEP_CAPS_LOCKED))
642 error = -EPERM;
643 else if (arg2)
644 current->securebits |= issecure_mask(SECURE_KEEP_CAPS);
645 else
646 current->securebits &=
647 ~issecure_mask(SECURE_KEEP_CAPS);
648 break;
649
650 default:
651 /* No functionality available - continue with default */
652 return 0;
653 }
654
655 /* Functionality provided */
656 *rc_p = error;
657 return 1;
658}
659
575void cap_task_reparent_to_init (struct task_struct *p) 660void cap_task_reparent_to_init (struct task_struct *p)
576{ 661{
577 cap_set_init_eff(p->cap_effective); 662 cap_set_init_eff(p->cap_effective);
578 cap_clear(p->cap_inheritable); 663 cap_clear(p->cap_inheritable);
579 cap_set_full(p->cap_permitted); 664 cap_set_full(p->cap_permitted);
580 p->keep_capabilities = 0; 665 p->securebits = SECUREBITS_DEFAULT;
581 return; 666 return;
582} 667}
583 668
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
new file mode 100644
index 000000000000..4ea583689eec
--- /dev/null
+++ b/security/device_cgroup.c
@@ -0,0 +1,575 @@
1/*
2 * dev_cgroup.c - device cgroup subsystem
3 *
4 * Copyright 2007 IBM Corp
5 */
6
7#include <linux/device_cgroup.h>
8#include <linux/cgroup.h>
9#include <linux/ctype.h>
10#include <linux/list.h>
11#include <linux/uaccess.h>
12#include <linux/seq_file.h>
13
14#define ACC_MKNOD 1
15#define ACC_READ 2
16#define ACC_WRITE 4
17#define ACC_MASK (ACC_MKNOD | ACC_READ | ACC_WRITE)
18
19#define DEV_BLOCK 1
20#define DEV_CHAR 2
21#define DEV_ALL 4 /* this represents all devices */
22
23/*
24 * whitelist locking rules:
25 * cgroup_lock() cannot be taken under dev_cgroup->lock.
26 * dev_cgroup->lock can be taken with or without cgroup_lock().
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 */
38
39struct dev_whitelist_item {
40 u32 major, minor;
41 short type;
42 short access;
43 struct list_head list;
44};
45
46struct dev_cgroup {
47 struct cgroup_subsys_state css;
48 struct list_head whitelist;
49 spinlock_t lock;
50};
51
52static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup)
53{
54 return container_of(cgroup_subsys_state(cgroup, devices_subsys_id),
55 struct dev_cgroup, css);
56}
57
58struct cgroup_subsys devices_subsys;
59
60static int devcgroup_can_attach(struct cgroup_subsys *ss,
61 struct cgroup *new_cgroup, struct task_struct *task)
62{
63 if (current != task && !capable(CAP_SYS_ADMIN))
64 return -EPERM;
65
66 return 0;
67}
68
69/*
70 * called under cgroup_lock()
71 */
72static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
73{
74 struct dev_whitelist_item *wh, *tmp, *new;
75
76 list_for_each_entry(wh, orig, list) {
77 new = kmalloc(sizeof(*wh), GFP_KERNEL);
78 if (!new)
79 goto free_and_exit;
80 new->major = wh->major;
81 new->minor = wh->minor;
82 new->type = wh->type;
83 new->access = wh->access;
84 list_add_tail(&new->list, dest);
85 }
86
87 return 0;
88
89free_and_exit:
90 list_for_each_entry_safe(wh, tmp, dest, list) {
91 list_del(&wh->list);
92 kfree(wh);
93 }
94 return -ENOMEM;
95}
96
97/* Stupid prototype - don't bother combining existing entries */
98/*
99 * called under cgroup_lock()
100 * since the list is visible to other tasks, we need the spinlock also
101 */
102static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
103 struct dev_whitelist_item *wh)
104{
105 struct dev_whitelist_item *whcopy;
106
107 whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL);
108 if (!whcopy)
109 return -ENOMEM;
110
111 memcpy(whcopy, wh, sizeof(*whcopy));
112 spin_lock(&dev_cgroup->lock);
113 list_add_tail(&whcopy->list, &dev_cgroup->whitelist);
114 spin_unlock(&dev_cgroup->lock);
115 return 0;
116}
117
118/*
119 * called under cgroup_lock()
120 * since the list is visible to other tasks, we need the spinlock also
121 */
122static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup,
123 struct dev_whitelist_item *wh)
124{
125 struct dev_whitelist_item *walk, *tmp;
126
127 spin_lock(&dev_cgroup->lock);
128 list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) {
129 if (walk->type == DEV_ALL)
130 goto remove;
131 if (walk->type != wh->type)
132 continue;
133 if (walk->major != ~0 && walk->major != wh->major)
134 continue;
135 if (walk->minor != ~0 && walk->minor != wh->minor)
136 continue;
137
138remove:
139 walk->access &= ~wh->access;
140 if (!walk->access) {
141 list_del(&walk->list);
142 kfree(walk);
143 }
144 }
145 spin_unlock(&dev_cgroup->lock);
146}
147
148/*
149 * called from kernel/cgroup.c with cgroup_lock() held.
150 */
151static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
152 struct cgroup *cgroup)
153{
154 struct dev_cgroup *dev_cgroup, *parent_dev_cgroup;
155 struct cgroup *parent_cgroup;
156 int ret;
157
158 dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL);
159 if (!dev_cgroup)
160 return ERR_PTR(-ENOMEM);
161 INIT_LIST_HEAD(&dev_cgroup->whitelist);
162 parent_cgroup = cgroup->parent;
163
164 if (parent_cgroup == NULL) {
165 struct dev_whitelist_item *wh;
166 wh = kmalloc(sizeof(*wh), GFP_KERNEL);
167 if (!wh) {
168 kfree(dev_cgroup);
169 return ERR_PTR(-ENOMEM);
170 }
171 wh->minor = wh->major = ~0;
172 wh->type = DEV_ALL;
173 wh->access = ACC_MKNOD | ACC_READ | ACC_WRITE;
174 list_add(&wh->list, &dev_cgroup->whitelist);
175 } else {
176 parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup);
177 ret = dev_whitelist_copy(&dev_cgroup->whitelist,
178 &parent_dev_cgroup->whitelist);
179 if (ret) {
180 kfree(dev_cgroup);
181 return ERR_PTR(ret);
182 }
183 }
184
185 spin_lock_init(&dev_cgroup->lock);
186 return &dev_cgroup->css;
187}
188
189static void devcgroup_destroy(struct cgroup_subsys *ss,
190 struct cgroup *cgroup)
191{
192 struct dev_cgroup *dev_cgroup;
193 struct dev_whitelist_item *wh, *tmp;
194
195 dev_cgroup = cgroup_to_devcgroup(cgroup);
196 list_for_each_entry_safe(wh, tmp, &dev_cgroup->whitelist, list) {
197 list_del(&wh->list);
198 kfree(wh);
199 }
200 kfree(dev_cgroup);
201}
202
203#define DEVCG_ALLOW 1
204#define DEVCG_DENY 2
205#define DEVCG_LIST 3
206
207#define MAJMINLEN 10
208#define ACCLEN 4
209
210static void set_access(char *acc, short access)
211{
212 int idx = 0;
213 memset(acc, 0, ACCLEN);
214 if (access & ACC_READ)
215 acc[idx++] = 'r';
216 if (access & ACC_WRITE)
217 acc[idx++] = 'w';
218 if (access & ACC_MKNOD)
219 acc[idx++] = 'm';
220}
221
222static char type_to_char(short type)
223{
224 if (type == DEV_ALL)
225 return 'a';
226 if (type == DEV_CHAR)
227 return 'c';
228 if (type == DEV_BLOCK)
229 return 'b';
230 return 'X';
231}
232
233static void set_majmin(char *str, unsigned m)
234{
235 memset(str, 0, MAJMINLEN);
236 if (m == ~0)
237 sprintf(str, "*");
238 else
239 snprintf(str, MAJMINLEN, "%d", m);
240}
241
242static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft,
243 struct seq_file *m)
244{
245 struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
246 struct dev_whitelist_item *wh;
247 char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
248
249 spin_lock(&devcgroup->lock);
250 list_for_each_entry(wh, &devcgroup->whitelist, list) {
251 set_access(acc, wh->access);
252 set_majmin(maj, wh->major);
253 set_majmin(min, wh->minor);
254 seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type),
255 maj, min, acc);
256 }
257 spin_unlock(&devcgroup->lock);
258
259 return 0;
260}
261
262/*
263 * may_access_whitelist:
264 * does the access granted to dev_cgroup c contain the access
265 * requested in whitelist item refwh.
266 * return 1 if yes, 0 if no.
267 * call with c->lock held
268 */
269static int may_access_whitelist(struct dev_cgroup *c,
270 struct dev_whitelist_item *refwh)
271{
272 struct dev_whitelist_item *whitem;
273
274 list_for_each_entry(whitem, &c->whitelist, list) {
275 if (whitem->type & DEV_ALL)
276 return 1;
277 if ((refwh->type & DEV_BLOCK) && !(whitem->type & DEV_BLOCK))
278 continue;
279 if ((refwh->type & DEV_CHAR) && !(whitem->type & DEV_CHAR))
280 continue;
281 if (whitem->major != ~0 && whitem->major != refwh->major)
282 continue;
283 if (whitem->minor != ~0 && whitem->minor != refwh->minor)
284 continue;
285 if (refwh->access & (~(whitem->access | ACC_MASK)))
286 continue;
287 return 1;
288 }
289 return 0;
290}
291
292/*
293 * parent_has_perm:
294 * when adding a new allow rule to a device whitelist, the rule
295 * must be allowed in the parent device
296 */
297static int parent_has_perm(struct cgroup *childcg,
298 struct dev_whitelist_item *wh)
299{
300 struct cgroup *pcg = childcg->parent;
301 struct dev_cgroup *parent;
302 int ret;
303
304 if (!pcg)
305 return 1;
306 parent = cgroup_to_devcgroup(pcg);
307 spin_lock(&parent->lock);
308 ret = may_access_whitelist(parent, wh);
309 spin_unlock(&parent->lock);
310 return ret;
311}
312
313/*
314 * Modify the whitelist using allow/deny rules.
315 * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD
316 * so we can give a container CAP_MKNOD to let it create devices but not
317 * modify the whitelist.
318 * It seems likely we'll want to add a CAP_CONTAINER capability to allow
319 * us to also grant CAP_SYS_ADMIN to containers without giving away the
320 * device whitelist controls, but for now we'll stick with CAP_SYS_ADMIN
321 *
322 * Taking rules away is always allowed (given CAP_SYS_ADMIN). Granting
323 * new access is only allowed if you're in the top-level cgroup, or your
324 * parent cgroup has the access you're asking for.
325 */
326static ssize_t devcgroup_access_write(struct cgroup *cgroup, struct cftype *cft,
327 struct file *file, const char __user *userbuf,
328 size_t nbytes, loff_t *ppos)
329{
330 struct cgroup *cur_cgroup;
331 struct dev_cgroup *devcgroup, *cur_devcgroup;
332 int filetype = cft->private;
333 char *buffer, *b;
334 int retval = 0, count;
335 struct dev_whitelist_item wh;
336
337 if (!capable(CAP_SYS_ADMIN))
338 return -EPERM;
339
340 devcgroup = cgroup_to_devcgroup(cgroup);
341 cur_cgroup = task_cgroup(current, devices_subsys.subsys_id);
342 cur_devcgroup = cgroup_to_devcgroup(cur_cgroup);
343
344 buffer = kmalloc(nbytes+1, GFP_KERNEL);
345 if (!buffer)
346 return -ENOMEM;
347
348 if (copy_from_user(buffer, userbuf, nbytes)) {
349 retval = -EFAULT;
350 goto out1;
351 }
352 buffer[nbytes] = 0; /* nul-terminate */
353
354 cgroup_lock();
355 if (cgroup_is_removed(cgroup)) {
356 retval = -ENODEV;
357 goto out2;
358 }
359
360 memset(&wh, 0, sizeof(wh));
361 b = buffer;
362
363 switch (*b) {
364 case 'a':
365 wh.type = DEV_ALL;
366 wh.access = ACC_MASK;
367 goto handle;
368 case 'b':
369 wh.type = DEV_BLOCK;
370 break;
371 case 'c':
372 wh.type = DEV_CHAR;
373 break;
374 default:
375 retval = -EINVAL;
376 goto out2;
377 }
378 b++;
379 if (!isspace(*b)) {
380 retval = -EINVAL;
381 goto out2;
382 }
383 b++;
384 if (*b == '*') {
385 wh.major = ~0;
386 b++;
387 } else if (isdigit(*b)) {
388 wh.major = 0;
389 while (isdigit(*b)) {
390 wh.major = wh.major*10+(*b-'0');
391 b++;
392 }
393 } else {
394 retval = -EINVAL;
395 goto out2;
396 }
397 if (*b != ':') {
398 retval = -EINVAL;
399 goto out2;
400 }
401 b++;
402
403 /* read minor */
404 if (*b == '*') {
405 wh.minor = ~0;
406 b++;
407 } else if (isdigit(*b)) {
408 wh.minor = 0;
409 while (isdigit(*b)) {
410 wh.minor = wh.minor*10+(*b-'0');
411 b++;
412 }
413 } else {
414 retval = -EINVAL;
415 goto out2;
416 }
417 if (!isspace(*b)) {
418 retval = -EINVAL;
419 goto out2;
420 }
421 for (b++, count = 0; count < 3; count++, b++) {
422 switch (*b) {
423 case 'r':
424 wh.access |= ACC_READ;
425 break;
426 case 'w':
427 wh.access |= ACC_WRITE;
428 break;
429 case 'm':
430 wh.access |= ACC_MKNOD;
431 break;
432 case '\n':
433 case '\0':
434 count = 3;
435 break;
436 default:
437 retval = -EINVAL;
438 goto out2;
439 }
440 }
441
442handle:
443 retval = 0;
444 switch (filetype) {
445 case DEVCG_ALLOW:
446 if (!parent_has_perm(cgroup, &wh))
447 retval = -EPERM;
448 else
449 retval = dev_whitelist_add(devcgroup, &wh);
450 break;
451 case DEVCG_DENY:
452 dev_whitelist_rm(devcgroup, &wh);
453 break;
454 default:
455 retval = -EINVAL;
456 goto out2;
457 }
458
459 if (retval == 0)
460 retval = nbytes;
461
462out2:
463 cgroup_unlock();
464out1:
465 kfree(buffer);
466 return retval;
467}
468
469static struct cftype dev_cgroup_files[] = {
470 {
471 .name = "allow",
472 .write = devcgroup_access_write,
473 .private = DEVCG_ALLOW,
474 },
475 {
476 .name = "deny",
477 .write = devcgroup_access_write,
478 .private = DEVCG_DENY,
479 },
480 {
481 .name = "list",
482 .read_seq_string = devcgroup_seq_read,
483 .private = DEVCG_LIST,
484 },
485};
486
487static int devcgroup_populate(struct cgroup_subsys *ss,
488 struct cgroup *cgroup)
489{
490 return cgroup_add_files(cgroup, ss, dev_cgroup_files,
491 ARRAY_SIZE(dev_cgroup_files));
492}
493
494struct cgroup_subsys devices_subsys = {
495 .name = "devices",
496 .can_attach = devcgroup_can_attach,
497 .create = devcgroup_create,
498 .destroy = devcgroup_destroy,
499 .populate = devcgroup_populate,
500 .subsys_id = devices_subsys_id,
501};
502
503int devcgroup_inode_permission(struct inode *inode, int mask)
504{
505 struct cgroup *cgroup;
506 struct dev_cgroup *dev_cgroup;
507 struct dev_whitelist_item *wh;
508
509 dev_t device = inode->i_rdev;
510 if (!device)
511 return 0;
512 if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode))
513 return 0;
514 cgroup = task_cgroup(current, devices_subsys.subsys_id);
515 dev_cgroup = cgroup_to_devcgroup(cgroup);
516 if (!dev_cgroup)
517 return 0;
518
519 spin_lock(&dev_cgroup->lock);
520 list_for_each_entry(wh, &dev_cgroup->whitelist, list) {
521 if (wh->type & DEV_ALL)
522 goto acc_check;
523 if ((wh->type & DEV_BLOCK) && !S_ISBLK(inode->i_mode))
524 continue;
525 if ((wh->type & DEV_CHAR) && !S_ISCHR(inode->i_mode))
526 continue;
527 if (wh->major != ~0 && wh->major != imajor(inode))
528 continue;
529 if (wh->minor != ~0 && wh->minor != iminor(inode))
530 continue;
531acc_check:
532 if ((mask & MAY_WRITE) && !(wh->access & ACC_WRITE))
533 continue;
534 if ((mask & MAY_READ) && !(wh->access & ACC_READ))
535 continue;
536 spin_unlock(&dev_cgroup->lock);
537 return 0;
538 }
539 spin_unlock(&dev_cgroup->lock);
540
541 return -EPERM;
542}
543
544int devcgroup_inode_mknod(int mode, dev_t dev)
545{
546 struct cgroup *cgroup;
547 struct dev_cgroup *dev_cgroup;
548 struct dev_whitelist_item *wh;
549
550 cgroup = task_cgroup(current, devices_subsys.subsys_id);
551 dev_cgroup = cgroup_to_devcgroup(cgroup);
552 if (!dev_cgroup)
553 return 0;
554
555 spin_lock(&dev_cgroup->lock);
556 list_for_each_entry(wh, &dev_cgroup->whitelist, list) {
557 if (wh->type & DEV_ALL)
558 goto acc_check;
559 if ((wh->type & DEV_BLOCK) && !S_ISBLK(mode))
560 continue;
561 if ((wh->type & DEV_CHAR) && !S_ISCHR(mode))
562 continue;
563 if (wh->major != ~0 && wh->major != MAJOR(dev))
564 continue;
565 if (wh->minor != ~0 && wh->minor != MINOR(dev))
566 continue;
567acc_check:
568 if (!(wh->access & ACC_MKNOD))
569 continue;
570 spin_unlock(&dev_cgroup->lock);
571 return 0;
572 }
573 spin_unlock(&dev_cgroup->lock);
574 return -EPERM;
575}
diff --git a/security/dummy.c b/security/dummy.c
index b0232bbf427b..48cf30226e16 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -365,8 +365,8 @@ static void dummy_inode_delete (struct inode *ino)
365 return; 365 return;
366} 366}
367 367
368static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value, 368static int dummy_inode_setxattr (struct dentry *dentry, const char *name,
369 size_t size, int flags) 369 const void *value, size_t size, int flags)
370{ 370{
371 if (!strncmp(name, XATTR_SECURITY_PREFIX, 371 if (!strncmp(name, XATTR_SECURITY_PREFIX,
372 sizeof(XATTR_SECURITY_PREFIX) - 1) && 372 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
@@ -375,12 +375,13 @@ static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value,
375 return 0; 375 return 0;
376} 376}
377 377
378static void dummy_inode_post_setxattr (struct dentry *dentry, char *name, void *value, 378static void dummy_inode_post_setxattr (struct dentry *dentry, const char *name,
379 size_t size, int flags) 379 const void *value, size_t size,
380 int flags)
380{ 381{
381} 382}
382 383
383static int dummy_inode_getxattr (struct dentry *dentry, char *name) 384static int dummy_inode_getxattr (struct dentry *dentry, const char *name)
384{ 385{
385 return 0; 386 return 0;
386} 387}
@@ -390,7 +391,7 @@ static int dummy_inode_listxattr (struct dentry *dentry)
390 return 0; 391 return 0;
391} 392}
392 393
393static int dummy_inode_removexattr (struct dentry *dentry, char *name) 394static int dummy_inode_removexattr (struct dentry *dentry, const char *name)
394{ 395{
395 if (!strncmp(name, XATTR_SECURITY_PREFIX, 396 if (!strncmp(name, XATTR_SECURITY_PREFIX,
396 sizeof(XATTR_SECURITY_PREFIX) - 1) && 397 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
@@ -604,7 +605,7 @@ static int dummy_task_kill (struct task_struct *p, struct siginfo *info,
604} 605}
605 606
606static int dummy_task_prctl (int option, unsigned long arg2, unsigned long arg3, 607static int dummy_task_prctl (int option, unsigned long arg2, unsigned long arg3,
607 unsigned long arg4, unsigned long arg5) 608 unsigned long arg4, unsigned long arg5, long *rc_p)
608{ 609{
609 return 0; 610 return 0;
610} 611}
@@ -993,6 +994,13 @@ static inline int dummy_key_permission(key_ref_t key_ref,
993{ 994{
994 return 0; 995 return 0;
995} 996}
997
998static int dummy_key_getsecurity(struct key *key, char **_buffer)
999{
1000 *_buffer = NULL;
1001 return 0;
1002}
1003
996#endif /* CONFIG_KEYS */ 1004#endif /* CONFIG_KEYS */
997 1005
998#ifdef CONFIG_AUDIT 1006#ifdef CONFIG_AUDIT
@@ -1209,6 +1217,7 @@ void security_fixup_ops (struct security_operations *ops)
1209 set_to_dummy_if_null(ops, key_alloc); 1217 set_to_dummy_if_null(ops, key_alloc);
1210 set_to_dummy_if_null(ops, key_free); 1218 set_to_dummy_if_null(ops, key_free);
1211 set_to_dummy_if_null(ops, key_permission); 1219 set_to_dummy_if_null(ops, key_permission);
1220 set_to_dummy_if_null(ops, key_getsecurity);
1212#endif /* CONFIG_KEYS */ 1221#endif /* CONFIG_KEYS */
1213#ifdef CONFIG_AUDIT 1222#ifdef CONFIG_AUDIT
1214 set_to_dummy_if_null(ops, audit_rule_init); 1223 set_to_dummy_if_null(ops, audit_rule_init);
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 5145adfb6a05..747a464943af 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,3 +14,4 @@ obj-y := \
14 14
15obj-$(CONFIG_KEYS_COMPAT) += compat.o 15obj-$(CONFIG_KEYS_COMPAT) += compat.o
16obj-$(CONFIG_PROC_FS) += proc.o 16obj-$(CONFIG_PROC_FS) += proc.o
17obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/compat.c b/security/keys/compat.c
index e10ec995f275..c766c68a63bc 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -79,6 +79,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
79 case KEYCTL_ASSUME_AUTHORITY: 79 case KEYCTL_ASSUME_AUTHORITY:
80 return keyctl_assume_authority(arg2); 80 return keyctl_assume_authority(arg2);
81 81
82 case KEYCTL_GET_SECURITY:
83 return keyctl_get_security(arg2, compat_ptr(arg3), arg4);
84
82 default: 85 default:
83 return -EOPNOTSUPP; 86 return -EOPNOTSUPP;
84 } 87 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 7d894ef70370..8c05587f5018 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -57,10 +57,6 @@ struct key_user {
57 int qnbytes; /* number of bytes allocated to this user */ 57 int qnbytes; /* number of bytes allocated to this user */
58}; 58};
59 59
60#define KEYQUOTA_MAX_KEYS 100
61#define KEYQUOTA_MAX_BYTES 10000
62#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */
63
64extern struct rb_root key_user_tree; 60extern struct rb_root key_user_tree;
65extern spinlock_t key_user_lock; 61extern spinlock_t key_user_lock;
66extern struct key_user root_key_user; 62extern struct key_user root_key_user;
@@ -68,6 +64,16 @@ extern struct key_user root_key_user;
68extern struct key_user *key_user_lookup(uid_t uid); 64extern struct key_user *key_user_lookup(uid_t uid);
69extern void key_user_put(struct key_user *user); 65extern void key_user_put(struct key_user *user);
70 66
67/*
68 * key quota limits
69 * - root has its own separate limits to everyone else
70 */
71extern unsigned key_quota_root_maxkeys;
72extern unsigned key_quota_root_maxbytes;
73extern unsigned key_quota_maxkeys;
74extern unsigned key_quota_maxbytes;
75
76#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */
71 77
72 78
73extern struct rb_root key_serial_tree; 79extern struct rb_root key_serial_tree;
@@ -77,8 +83,6 @@ extern struct mutex key_construction_mutex;
77extern wait_queue_head_t request_key_conswq; 83extern wait_queue_head_t request_key_conswq;
78 84
79 85
80extern void keyring_publish_name(struct key *keyring);
81
82extern int __key_link(struct key *keyring, struct key *key); 86extern int __key_link(struct key *keyring, struct key *key);
83 87
84extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, 88extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
@@ -102,14 +106,15 @@ extern key_ref_t search_process_keyrings(struct key_type *type,
102 key_match_func_t match, 106 key_match_func_t match,
103 struct task_struct *tsk); 107 struct task_struct *tsk);
104 108
105extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); 109extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
106 110
107extern int install_thread_keyring(struct task_struct *tsk); 111extern int install_thread_keyring(struct task_struct *tsk);
108extern int install_process_keyring(struct task_struct *tsk); 112extern int install_process_keyring(struct task_struct *tsk);
109 113
110extern struct key *request_key_and_link(struct key_type *type, 114extern struct key *request_key_and_link(struct key_type *type,
111 const char *description, 115 const char *description,
112 const char *callout_info, 116 const void *callout_info,
117 size_t callout_len,
113 void *aux, 118 void *aux,
114 struct key *dest_keyring, 119 struct key *dest_keyring,
115 unsigned long flags); 120 unsigned long flags);
@@ -120,13 +125,15 @@ extern struct key *request_key_and_link(struct key_type *type,
120struct request_key_auth { 125struct request_key_auth {
121 struct key *target_key; 126 struct key *target_key;
122 struct task_struct *context; 127 struct task_struct *context;
123 char *callout_info; 128 void *callout_info;
129 size_t callout_len;
124 pid_t pid; 130 pid_t pid;
125}; 131};
126 132
127extern struct key_type key_type_request_key_auth; 133extern struct key_type key_type_request_key_auth;
128extern struct key *request_key_auth_new(struct key *target, 134extern struct key *request_key_auth_new(struct key *target,
129 const char *callout_info); 135 const void *callout_info,
136 size_t callout_len);
130 137
131extern struct key *key_get_instantiation_authkey(key_serial_t target_id); 138extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
132 139
@@ -152,7 +159,8 @@ extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
152extern long keyctl_set_reqkey_keyring(int); 159extern long keyctl_set_reqkey_keyring(int);
153extern long keyctl_set_timeout(key_serial_t, unsigned); 160extern long keyctl_set_timeout(key_serial_t, unsigned);
154extern long keyctl_assume_authority(key_serial_t); 161extern long keyctl_assume_authority(key_serial_t);
155 162extern long keyctl_get_security(key_serial_t keyid, char __user *buffer,
163 size_t buflen);
156 164
157/* 165/*
158 * debugging key validation 166 * debugging key validation
diff --git a/security/keys/key.c b/security/keys/key.c
index 654d23baf352..14948cf83ef6 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
1/* Basic authentication token and access key management 1/* Basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -27,6 +27,11 @@ DEFINE_SPINLOCK(key_serial_lock);
27struct rb_root key_user_tree; /* tree of quota records indexed by UID */ 27struct rb_root key_user_tree; /* tree of quota records indexed by UID */
28DEFINE_SPINLOCK(key_user_lock); 28DEFINE_SPINLOCK(key_user_lock);
29 29
30unsigned int key_quota_root_maxkeys = 200; /* root's key count quota */
31unsigned int key_quota_root_maxbytes = 20000; /* root's key space quota */
32unsigned int key_quota_maxkeys = 200; /* general key count quota */
33unsigned int key_quota_maxbytes = 20000; /* general key space quota */
34
30static LIST_HEAD(key_types_list); 35static LIST_HEAD(key_types_list);
31static DECLARE_RWSEM(key_types_sem); 36static DECLARE_RWSEM(key_types_sem);
32 37
@@ -139,36 +144,6 @@ void key_user_put(struct key_user *user)
139 144
140/*****************************************************************************/ 145/*****************************************************************************/
141/* 146/*
142 * insert a key with a fixed serial number
143 */
144static void __init __key_insert_serial(struct key *key)
145{
146 struct rb_node *parent, **p;
147 struct key *xkey;
148
149 parent = NULL;
150 p = &key_serial_tree.rb_node;
151
152 while (*p) {
153 parent = *p;
154 xkey = rb_entry(parent, struct key, serial_node);
155
156 if (key->serial < xkey->serial)
157 p = &(*p)->rb_left;
158 else if (key->serial > xkey->serial)
159 p = &(*p)->rb_right;
160 else
161 BUG();
162 }
163
164 /* we've found a suitable hole - arrange for this key to occupy it */
165 rb_link_node(&key->serial_node, parent, p);
166 rb_insert_color(&key->serial_node, &key_serial_tree);
167
168} /* end __key_insert_serial() */
169
170/*****************************************************************************/
171/*
172 * assign a key the next unique serial number 147 * assign a key the next unique serial number
173 * - these are assigned randomly to avoid security issues through covert 148 * - these are assigned randomly to avoid security issues through covert
174 * channel problems 149 * channel problems
@@ -266,11 +241,16 @@ struct key *key_alloc(struct key_type *type, const char *desc,
266 /* check that the user's quota permits allocation of another key and 241 /* check that the user's quota permits allocation of another key and
267 * its description */ 242 * its description */
268 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { 243 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
244 unsigned maxkeys = (uid == 0) ?
245 key_quota_root_maxkeys : key_quota_maxkeys;
246 unsigned maxbytes = (uid == 0) ?
247 key_quota_root_maxbytes : key_quota_maxbytes;
248
269 spin_lock(&user->lock); 249 spin_lock(&user->lock);
270 if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) { 250 if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
271 if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || 251 if (user->qnkeys + 1 >= maxkeys ||
272 user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES 252 user->qnbytes + quotalen >= maxbytes ||
273 ) 253 user->qnbytes + quotalen < user->qnbytes)
274 goto no_quota; 254 goto no_quota;
275 } 255 }
276 256
@@ -375,11 +355,14 @@ int key_payload_reserve(struct key *key, size_t datalen)
375 355
376 /* contemplate the quota adjustment */ 356 /* contemplate the quota adjustment */
377 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 357 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
358 unsigned maxbytes = (key->user->uid == 0) ?
359 key_quota_root_maxbytes : key_quota_maxbytes;
360
378 spin_lock(&key->user->lock); 361 spin_lock(&key->user->lock);
379 362
380 if (delta > 0 && 363 if (delta > 0 &&
381 key->user->qnbytes + delta > KEYQUOTA_MAX_BYTES 364 (key->user->qnbytes + delta >= maxbytes ||
382 ) { 365 key->user->qnbytes + delta < key->user->qnbytes)) {
383 ret = -EDQUOT; 366 ret = -EDQUOT;
384 } 367 }
385 else { 368 else {
@@ -757,11 +740,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
757 const char *description, 740 const char *description,
758 const void *payload, 741 const void *payload,
759 size_t plen, 742 size_t plen,
743 key_perm_t perm,
760 unsigned long flags) 744 unsigned long flags)
761{ 745{
762 struct key_type *ktype; 746 struct key_type *ktype;
763 struct key *keyring, *key = NULL; 747 struct key *keyring, *key = NULL;
764 key_perm_t perm;
765 key_ref_t key_ref; 748 key_ref_t key_ref;
766 int ret; 749 int ret;
767 750
@@ -806,15 +789,17 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
806 goto found_matching_key; 789 goto found_matching_key;
807 } 790 }
808 791
809 /* decide on the permissions we want */ 792 /* if the client doesn't provide, decide on the permissions we want */
810 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 793 if (perm == KEY_PERM_UNDEF) {
811 perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR; 794 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
795 perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
812 796
813 if (ktype->read) 797 if (ktype->read)
814 perm |= KEY_POS_READ | KEY_USR_READ; 798 perm |= KEY_POS_READ | KEY_USR_READ;
815 799
816 if (ktype == &key_type_keyring || ktype->update) 800 if (ktype == &key_type_keyring || ktype->update)
817 perm |= KEY_USR_WRITE; 801 perm |= KEY_USR_WRITE;
802 }
818 803
819 /* allocate a new key */ 804 /* allocate a new key */
820 key = key_alloc(ktype, description, current->fsuid, current->fsgid, 805 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
@@ -1018,17 +1003,4 @@ void __init key_init(void)
1018 rb_insert_color(&root_key_user.node, 1003 rb_insert_color(&root_key_user.node,
1019 &key_user_tree); 1004 &key_user_tree);
1020 1005
1021 /* record root's user standard keyrings */
1022 key_check(&root_user_keyring);
1023 key_check(&root_session_keyring);
1024
1025 __key_insert_serial(&root_user_keyring);
1026 __key_insert_serial(&root_session_keyring);
1027
1028 keyring_publish_name(&root_user_keyring);
1029 keyring_publish_name(&root_session_keyring);
1030
1031 /* link the two root keyrings together */
1032 key_link(&root_session_keyring, &root_user_keyring);
1033
1034} /* end key_init() */ 1006} /* end key_init() */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index d9ca15c109cc..acc9c89e40a8 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -19,6 +19,8 @@
19#include <linux/capability.h> 19#include <linux/capability.h>
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/vmalloc.h>
23#include <linux/security.h>
22#include <asm/uaccess.h> 24#include <asm/uaccess.h>
23#include "internal.h" 25#include "internal.h"
24 26
@@ -62,9 +64,10 @@ asmlinkage long sys_add_key(const char __user *_type,
62 char type[32], *description; 64 char type[32], *description;
63 void *payload; 65 void *payload;
64 long ret; 66 long ret;
67 bool vm;
65 68
66 ret = -EINVAL; 69 ret = -EINVAL;
67 if (plen > 32767) 70 if (plen > 1024 * 1024 - 1)
68 goto error; 71 goto error;
69 72
70 /* draw all the data into kernel space */ 73 /* draw all the data into kernel space */
@@ -81,11 +84,18 @@ asmlinkage long sys_add_key(const char __user *_type,
81 /* pull the payload in if one was supplied */ 84 /* pull the payload in if one was supplied */
82 payload = NULL; 85 payload = NULL;
83 86
87 vm = false;
84 if (_payload) { 88 if (_payload) {
85 ret = -ENOMEM; 89 ret = -ENOMEM;
86 payload = kmalloc(plen, GFP_KERNEL); 90 payload = kmalloc(plen, GFP_KERNEL);
87 if (!payload) 91 if (!payload) {
88 goto error2; 92 if (plen <= PAGE_SIZE)
93 goto error2;
94 vm = true;
95 payload = vmalloc(plen);
96 if (!payload)
97 goto error2;
98 }
89 99
90 ret = -EFAULT; 100 ret = -EFAULT;
91 if (copy_from_user(payload, _payload, plen) != 0) 101 if (copy_from_user(payload, _payload, plen) != 0)
@@ -102,7 +112,8 @@ asmlinkage long sys_add_key(const char __user *_type,
102 /* create or update the requested key and add it to the target 112 /* create or update the requested key and add it to the target
103 * keyring */ 113 * keyring */
104 key_ref = key_create_or_update(keyring_ref, type, description, 114 key_ref = key_create_or_update(keyring_ref, type, description,
105 payload, plen, KEY_ALLOC_IN_QUOTA); 115 payload, plen, KEY_PERM_UNDEF,
116 KEY_ALLOC_IN_QUOTA);
106 if (!IS_ERR(key_ref)) { 117 if (!IS_ERR(key_ref)) {
107 ret = key_ref_to_ptr(key_ref)->serial; 118 ret = key_ref_to_ptr(key_ref)->serial;
108 key_ref_put(key_ref); 119 key_ref_put(key_ref);
@@ -113,7 +124,10 @@ asmlinkage long sys_add_key(const char __user *_type,
113 124
114 key_ref_put(keyring_ref); 125 key_ref_put(keyring_ref);
115 error3: 126 error3:
116 kfree(payload); 127 if (!vm)
128 kfree(payload);
129 else
130 vfree(payload);
117 error2: 131 error2:
118 kfree(description); 132 kfree(description);
119 error: 133 error:
@@ -140,6 +154,7 @@ asmlinkage long sys_request_key(const char __user *_type,
140 struct key_type *ktype; 154 struct key_type *ktype;
141 struct key *key; 155 struct key *key;
142 key_ref_t dest_ref; 156 key_ref_t dest_ref;
157 size_t callout_len;
143 char type[32], *description, *callout_info; 158 char type[32], *description, *callout_info;
144 long ret; 159 long ret;
145 160
@@ -157,12 +172,14 @@ asmlinkage long sys_request_key(const char __user *_type,
157 172
158 /* pull the callout info into kernel space */ 173 /* pull the callout info into kernel space */
159 callout_info = NULL; 174 callout_info = NULL;
175 callout_len = 0;
160 if (_callout_info) { 176 if (_callout_info) {
161 callout_info = strndup_user(_callout_info, PAGE_SIZE); 177 callout_info = strndup_user(_callout_info, PAGE_SIZE);
162 if (IS_ERR(callout_info)) { 178 if (IS_ERR(callout_info)) {
163 ret = PTR_ERR(callout_info); 179 ret = PTR_ERR(callout_info);
164 goto error2; 180 goto error2;
165 } 181 }
182 callout_len = strlen(callout_info);
166 } 183 }
167 184
168 /* get the destination keyring if specified */ 185 /* get the destination keyring if specified */
@@ -183,8 +200,8 @@ asmlinkage long sys_request_key(const char __user *_type,
183 } 200 }
184 201
185 /* do the search */ 202 /* do the search */
186 key = request_key_and_link(ktype, description, callout_info, NULL, 203 key = request_key_and_link(ktype, description, callout_info,
187 key_ref_to_ptr(dest_ref), 204 callout_len, NULL, key_ref_to_ptr(dest_ref),
188 KEY_ALLOC_IN_QUOTA); 205 KEY_ALLOC_IN_QUOTA);
189 if (IS_ERR(key)) { 206 if (IS_ERR(key)) {
190 ret = PTR_ERR(key); 207 ret = PTR_ERR(key);
@@ -714,10 +731,16 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
714 731
715 /* transfer the quota burden to the new user */ 732 /* transfer the quota burden to the new user */
716 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 733 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
734 unsigned maxkeys = (uid == 0) ?
735 key_quota_root_maxkeys : key_quota_maxkeys;
736 unsigned maxbytes = (uid == 0) ?
737 key_quota_root_maxbytes : key_quota_maxbytes;
738
717 spin_lock(&newowner->lock); 739 spin_lock(&newowner->lock);
718 if (newowner->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || 740 if (newowner->qnkeys + 1 >= maxkeys ||
719 newowner->qnbytes + key->quotalen >= 741 newowner->qnbytes + key->quotalen >= maxbytes ||
720 KEYQUOTA_MAX_BYTES) 742 newowner->qnbytes + key->quotalen <
743 newowner->qnbytes)
721 goto quota_overrun; 744 goto quota_overrun;
722 745
723 newowner->qnkeys++; 746 newowner->qnkeys++;
@@ -821,9 +844,10 @@ long keyctl_instantiate_key(key_serial_t id,
821 key_ref_t keyring_ref; 844 key_ref_t keyring_ref;
822 void *payload; 845 void *payload;
823 long ret; 846 long ret;
847 bool vm = false;
824 848
825 ret = -EINVAL; 849 ret = -EINVAL;
826 if (plen > 32767) 850 if (plen > 1024 * 1024 - 1)
827 goto error; 851 goto error;
828 852
829 /* the appropriate instantiation authorisation key must have been 853 /* the appropriate instantiation authorisation key must have been
@@ -843,8 +867,14 @@ long keyctl_instantiate_key(key_serial_t id,
843 if (_payload) { 867 if (_payload) {
844 ret = -ENOMEM; 868 ret = -ENOMEM;
845 payload = kmalloc(plen, GFP_KERNEL); 869 payload = kmalloc(plen, GFP_KERNEL);
846 if (!payload) 870 if (!payload) {
847 goto error; 871 if (plen <= PAGE_SIZE)
872 goto error;
873 vm = true;
874 payload = vmalloc(plen);
875 if (!payload)
876 goto error;
877 }
848 878
849 ret = -EFAULT; 879 ret = -EFAULT;
850 if (copy_from_user(payload, _payload, plen) != 0) 880 if (copy_from_user(payload, _payload, plen) != 0)
@@ -877,7 +907,10 @@ long keyctl_instantiate_key(key_serial_t id,
877 } 907 }
878 908
879error2: 909error2:
880 kfree(payload); 910 if (!vm)
911 kfree(payload);
912 else
913 vfree(payload);
881error: 914error:
882 return ret; 915 return ret;
883 916
@@ -1055,6 +1088,66 @@ error:
1055 1088
1056} /* end keyctl_assume_authority() */ 1089} /* end keyctl_assume_authority() */
1057 1090
1091/*
1092 * get the security label of a key
1093 * - the key must grant us view permission
1094 * - if there's a buffer, we place up to buflen bytes of data into it
1095 * - unless there's an error, we return the amount of information available,
1096 * irrespective of how much we may have copied (including the terminal NUL)
1097 * - implements keyctl(KEYCTL_GET_SECURITY)
1098 */
1099long keyctl_get_security(key_serial_t keyid,
1100 char __user *buffer,
1101 size_t buflen)
1102{
1103 struct key *key, *instkey;
1104 key_ref_t key_ref;
1105 char *context;
1106 long ret;
1107
1108 key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
1109 if (IS_ERR(key_ref)) {
1110 if (PTR_ERR(key_ref) != -EACCES)
1111 return PTR_ERR(key_ref);
1112
1113 /* viewing a key under construction is also permitted if we
1114 * have the authorisation token handy */
1115 instkey = key_get_instantiation_authkey(keyid);
1116 if (IS_ERR(instkey))
1117 return PTR_ERR(key_ref);
1118 key_put(instkey);
1119
1120 key_ref = lookup_user_key(NULL, keyid, 0, 1, 0);
1121 if (IS_ERR(key_ref))
1122 return PTR_ERR(key_ref);
1123 }
1124
1125 key = key_ref_to_ptr(key_ref);
1126 ret = security_key_getsecurity(key, &context);
1127 if (ret == 0) {
1128 /* if no information was returned, give userspace an empty
1129 * string */
1130 ret = 1;
1131 if (buffer && buflen > 0 &&
1132 copy_to_user(buffer, "", 1) != 0)
1133 ret = -EFAULT;
1134 } else if (ret > 0) {
1135 /* return as much data as there's room for */
1136 if (buffer && buflen > 0) {
1137 if (buflen > ret)
1138 buflen = ret;
1139
1140 if (copy_to_user(buffer, context, buflen) != 0)
1141 ret = -EFAULT;
1142 }
1143
1144 kfree(context);
1145 }
1146
1147 key_ref_put(key_ref);
1148 return ret;
1149}
1150
1058/*****************************************************************************/ 1151/*****************************************************************************/
1059/* 1152/*
1060 * the key control system call 1153 * the key control system call
@@ -1135,6 +1228,11 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1135 case KEYCTL_ASSUME_AUTHORITY: 1228 case KEYCTL_ASSUME_AUTHORITY:
1136 return keyctl_assume_authority((key_serial_t) arg2); 1229 return keyctl_assume_authority((key_serial_t) arg2);
1137 1230
1231 case KEYCTL_GET_SECURITY:
1232 return keyctl_get_security((key_serial_t) arg2,
1233 (char *) arg3,
1234 (size_t) arg4);
1235
1138 default: 1236 default:
1139 return -EOPNOTSUPP; 1237 return -EOPNOTSUPP;
1140 } 1238 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 88292e3dee96..a9ab8affc092 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1,6 +1,6 @@
1/* keyring.c: keyring handling 1/* Keyring handling
2 * 2 *
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -79,7 +79,7 @@ static DECLARE_RWSEM(keyring_serialise_link_sem);
79 * publish the name of a keyring so that it can be found by name (if it has 79 * publish the name of a keyring so that it can be found by name (if it has
80 * one) 80 * one)
81 */ 81 */
82void keyring_publish_name(struct key *keyring) 82static void keyring_publish_name(struct key *keyring)
83{ 83{
84 int bucket; 84 int bucket;
85 85
@@ -292,7 +292,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
292 292
293 struct keyring_list *keylist; 293 struct keyring_list *keylist;
294 struct timespec now; 294 struct timespec now;
295 unsigned long possessed; 295 unsigned long possessed, kflags;
296 struct key *keyring, *key; 296 struct key *keyring, *key;
297 key_ref_t key_ref; 297 key_ref_t key_ref;
298 long err; 298 long err;
@@ -319,6 +319,32 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
319 err = -EAGAIN; 319 err = -EAGAIN;
320 sp = 0; 320 sp = 0;
321 321
322 /* firstly we should check to see if this top-level keyring is what we
323 * are looking for */
324 key_ref = ERR_PTR(-EAGAIN);
325 kflags = keyring->flags;
326 if (keyring->type == type && match(keyring, description)) {
327 key = keyring;
328
329 /* check it isn't negative and hasn't expired or been
330 * revoked */
331 if (kflags & (1 << KEY_FLAG_REVOKED))
332 goto error_2;
333 if (key->expiry && now.tv_sec >= key->expiry)
334 goto error_2;
335 key_ref = ERR_PTR(-ENOKEY);
336 if (kflags & (1 << KEY_FLAG_NEGATIVE))
337 goto error_2;
338 goto found;
339 }
340
341 /* otherwise, the top keyring must not be revoked, expired, or
342 * negatively instantiated if we are to search it */
343 key_ref = ERR_PTR(-EAGAIN);
344 if (kflags & ((1 << KEY_FLAG_REVOKED) | (1 << KEY_FLAG_NEGATIVE)) ||
345 (keyring->expiry && now.tv_sec >= keyring->expiry))
346 goto error_2;
347
322 /* start processing a new keyring */ 348 /* start processing a new keyring */
323descend: 349descend:
324 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 350 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -331,13 +357,14 @@ descend:
331 /* iterate through the keys in this keyring first */ 357 /* iterate through the keys in this keyring first */
332 for (kix = 0; kix < keylist->nkeys; kix++) { 358 for (kix = 0; kix < keylist->nkeys; kix++) {
333 key = keylist->keys[kix]; 359 key = keylist->keys[kix];
360 kflags = key->flags;
334 361
335 /* ignore keys not of this type */ 362 /* ignore keys not of this type */
336 if (key->type != type) 363 if (key->type != type)
337 continue; 364 continue;
338 365
339 /* skip revoked keys and expired keys */ 366 /* skip revoked keys and expired keys */
340 if (test_bit(KEY_FLAG_REVOKED, &key->flags)) 367 if (kflags & (1 << KEY_FLAG_REVOKED))
341 continue; 368 continue;
342 369
343 if (key->expiry && now.tv_sec >= key->expiry) 370 if (key->expiry && now.tv_sec >= key->expiry)
@@ -352,8 +379,8 @@ descend:
352 context, KEY_SEARCH) < 0) 379 context, KEY_SEARCH) < 0)
353 continue; 380 continue;
354 381
355 /* we set a different error code if we find a negative key */ 382 /* we set a different error code if we pass a negative key */
356 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 383 if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
357 err = -ENOKEY; 384 err = -ENOKEY;
358 continue; 385 continue;
359 } 386 }
@@ -489,10 +516,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
489/* 516/*
490 * find a keyring with the specified name 517 * find a keyring with the specified name
491 * - all named keyrings are searched 518 * - all named keyrings are searched
492 * - only find keyrings with search permission for the process 519 * - normally only finds keyrings with search permission for the current process
493 * - only find keyrings with a serial number greater than the one specified
494 */ 520 */
495struct key *find_keyring_by_name(const char *name, key_serial_t bound) 521struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
496{ 522{
497 struct key *keyring; 523 struct key *keyring;
498 int bucket; 524 int bucket;
@@ -518,15 +544,11 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
518 if (strcmp(keyring->description, name) != 0) 544 if (strcmp(keyring->description, name) != 0)
519 continue; 545 continue;
520 546
521 if (key_permission(make_key_ref(keyring, 0), 547 if (!skip_perm_check &&
548 key_permission(make_key_ref(keyring, 0),
522 KEY_SEARCH) < 0) 549 KEY_SEARCH) < 0)
523 continue; 550 continue;
524 551
525 /* found a potential candidate, but we still need to
526 * check the serial number */
527 if (keyring->serial <= bound)
528 continue;
529
530 /* we've got a match */ 552 /* we've got a match */
531 atomic_inc(&keyring->usage); 553 atomic_inc(&keyring->usage);
532 read_unlock(&keyring_name_lock); 554 read_unlock(&keyring_name_lock);
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 694126003ed3..f619170da760 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -70,19 +70,15 @@ static int __init key_proc_init(void)
70 struct proc_dir_entry *p; 70 struct proc_dir_entry *p;
71 71
72#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS 72#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS
73 p = create_proc_entry("keys", 0, NULL); 73 p = proc_create("keys", 0, NULL, &proc_keys_fops);
74 if (!p) 74 if (!p)
75 panic("Cannot create /proc/keys\n"); 75 panic("Cannot create /proc/keys\n");
76
77 p->proc_fops = &proc_keys_fops;
78#endif 76#endif
79 77
80 p = create_proc_entry("key-users", 0, NULL); 78 p = proc_create("key-users", 0, NULL, &proc_key_users_fops);
81 if (!p) 79 if (!p)
82 panic("Cannot create /proc/key-users\n"); 80 panic("Cannot create /proc/key-users\n");
83 81
84 p->proc_fops = &proc_key_users_fops;
85
86 return 0; 82 return 0;
87 83
88} /* end key_proc_init() */ 84} /* end key_proc_init() */
@@ -246,6 +242,10 @@ static int proc_key_users_show(struct seq_file *m, void *v)
246{ 242{
247 struct rb_node *_p = v; 243 struct rb_node *_p = v;
248 struct key_user *user = rb_entry(_p, struct key_user, node); 244 struct key_user *user = rb_entry(_p, struct key_user, node);
245 unsigned maxkeys = (user->uid == 0) ?
246 key_quota_root_maxkeys : key_quota_maxkeys;
247 unsigned maxbytes = (user->uid == 0) ?
248 key_quota_root_maxbytes : key_quota_maxbytes;
249 249
250 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", 250 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n",
251 user->uid, 251 user->uid,
@@ -253,10 +253,9 @@ static int proc_key_users_show(struct seq_file *m, void *v)
253 atomic_read(&user->nkeys), 253 atomic_read(&user->nkeys),
254 atomic_read(&user->nikeys), 254 atomic_read(&user->nikeys),
255 user->qnkeys, 255 user->qnkeys,
256 KEYQUOTA_MAX_KEYS, 256 maxkeys,
257 user->qnbytes, 257 user->qnbytes,
258 KEYQUOTA_MAX_BYTES 258 maxbytes);
259 );
260 259
261 return 0; 260 return 0;
262 261
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index c886a2bb792a..5be6d018759a 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -1,6 +1,6 @@
1/* process_keys.c: management of a process's keyrings 1/* Management of a process's keyrings
2 * 2 *
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -23,6 +23,9 @@
23/* session keyring create vs join semaphore */ 23/* session keyring create vs join semaphore */
24static DEFINE_MUTEX(key_session_mutex); 24static DEFINE_MUTEX(key_session_mutex);
25 25
26/* user keyring creation semaphore */
27static DEFINE_MUTEX(key_user_keyring_mutex);
28
26/* the root user's tracking struct */ 29/* the root user's tracking struct */
27struct key_user root_key_user = { 30struct key_user root_key_user = {
28 .usage = ATOMIC_INIT(3), 31 .usage = ATOMIC_INIT(3),
@@ -33,78 +36,84 @@ struct key_user root_key_user = {
33 .uid = 0, 36 .uid = 0,
34}; 37};
35 38
36/* the root user's UID keyring */
37struct key root_user_keyring = {
38 .usage = ATOMIC_INIT(1),
39 .serial = 2,
40 .type = &key_type_keyring,
41 .user = &root_key_user,
42 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
43 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
44 .flags = 1 << KEY_FLAG_INSTANTIATED,
45 .description = "_uid.0",
46#ifdef KEY_DEBUGGING
47 .magic = KEY_DEBUG_MAGIC,
48#endif
49};
50
51/* the root user's default session keyring */
52struct key root_session_keyring = {
53 .usage = ATOMIC_INIT(1),
54 .serial = 1,
55 .type = &key_type_keyring,
56 .user = &root_key_user,
57 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
58 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
59 .flags = 1 << KEY_FLAG_INSTANTIATED,
60 .description = "_uid_ses.0",
61#ifdef KEY_DEBUGGING
62 .magic = KEY_DEBUG_MAGIC,
63#endif
64};
65
66/*****************************************************************************/ 39/*****************************************************************************/
67/* 40/*
68 * allocate the keyrings to be associated with a UID 41 * install user and user session keyrings for a particular UID
69 */ 42 */
70int alloc_uid_keyring(struct user_struct *user, 43static int install_user_keyrings(struct task_struct *tsk)
71 struct task_struct *ctx)
72{ 44{
45 struct user_struct *user = tsk->user;
73 struct key *uid_keyring, *session_keyring; 46 struct key *uid_keyring, *session_keyring;
74 char buf[20]; 47 char buf[20];
75 int ret; 48 int ret;
76 49
77 /* concoct a default session keyring */ 50 kenter("%p{%u}", user, user->uid);
78 sprintf(buf, "_uid_ses.%u", user->uid);
79 51
80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 52 if (user->uid_keyring) {
81 KEY_ALLOC_IN_QUOTA, NULL); 53 kleave(" = 0 [exist]");
82 if (IS_ERR(session_keyring)) { 54 return 0;
83 ret = PTR_ERR(session_keyring);
84 goto error;
85 } 55 }
86 56
87 /* and a UID specific keyring, pointed to by the default session 57 mutex_lock(&key_user_keyring_mutex);
88 * keyring */ 58 ret = 0;
89 sprintf(buf, "_uid.%u", user->uid);
90 59
91 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 60 if (!user->uid_keyring) {
92 KEY_ALLOC_IN_QUOTA, session_keyring); 61 /* get the UID-specific keyring
93 if (IS_ERR(uid_keyring)) { 62 * - there may be one in existence already as it may have been
94 key_put(session_keyring); 63 * pinned by a session, but the user_struct pointing to it
95 ret = PTR_ERR(uid_keyring); 64 * may have been destroyed by setuid */
96 goto error; 65 sprintf(buf, "_uid.%u", user->uid);
66
67 uid_keyring = find_keyring_by_name(buf, true);
68 if (IS_ERR(uid_keyring)) {
69 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
70 tsk, KEY_ALLOC_IN_QUOTA,
71 NULL);
72 if (IS_ERR(uid_keyring)) {
73 ret = PTR_ERR(uid_keyring);
74 goto error;
75 }
76 }
77
78 /* get a default session keyring (which might also exist
79 * already) */
80 sprintf(buf, "_uid_ses.%u", user->uid);
81
82 session_keyring = find_keyring_by_name(buf, true);
83 if (IS_ERR(session_keyring)) {
84 session_keyring =
85 keyring_alloc(buf, user->uid, (gid_t) -1,
86 tsk, KEY_ALLOC_IN_QUOTA, NULL);
87 if (IS_ERR(session_keyring)) {
88 ret = PTR_ERR(session_keyring);
89 goto error_release;
90 }
91
92 /* we install a link from the user session keyring to
93 * the user keyring */
94 ret = key_link(session_keyring, uid_keyring);
95 if (ret < 0)
96 goto error_release_both;
97 }
98
99 /* install the keyrings */
100 user->uid_keyring = uid_keyring;
101 user->session_keyring = session_keyring;
97 } 102 }
98 103
99 /* install the keyrings */ 104 mutex_unlock(&key_user_keyring_mutex);
100 user->uid_keyring = uid_keyring; 105 kleave(" = 0");
101 user->session_keyring = session_keyring; 106 return 0;
102 ret = 0;
103 107
108error_release_both:
109 key_put(session_keyring);
110error_release:
111 key_put(uid_keyring);
104error: 112error:
113 mutex_unlock(&key_user_keyring_mutex);
114 kleave(" = %d", ret);
105 return ret; 115 return ret;
106 116}
107} /* end alloc_uid_keyring() */
108 117
109/*****************************************************************************/ 118/*****************************************************************************/
110/* 119/*
@@ -481,7 +490,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
481 } 490 }
482 } 491 }
483 /* or search the user-session keyring */ 492 /* or search the user-session keyring */
484 else { 493 else if (context->user->session_keyring) {
485 key_ref = keyring_search_aux( 494 key_ref = keyring_search_aux(
486 make_key_ref(context->user->session_keyring, 1), 495 make_key_ref(context->user->session_keyring, 1),
487 context, type, description, match); 496 context, type, description, match);
@@ -614,6 +623,9 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
614 if (!context->signal->session_keyring) { 623 if (!context->signal->session_keyring) {
615 /* always install a session keyring upon access if one 624 /* always install a session keyring upon access if one
616 * doesn't exist yet */ 625 * doesn't exist yet */
626 ret = install_user_keyrings(context);
627 if (ret < 0)
628 goto error;
617 ret = install_session_keyring( 629 ret = install_session_keyring(
618 context, context->user->session_keyring); 630 context, context->user->session_keyring);
619 if (ret < 0) 631 if (ret < 0)
@@ -628,12 +640,24 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
628 break; 640 break;
629 641
630 case KEY_SPEC_USER_KEYRING: 642 case KEY_SPEC_USER_KEYRING:
643 if (!context->user->uid_keyring) {
644 ret = install_user_keyrings(context);
645 if (ret < 0)
646 goto error;
647 }
648
631 key = context->user->uid_keyring; 649 key = context->user->uid_keyring;
632 atomic_inc(&key->usage); 650 atomic_inc(&key->usage);
633 key_ref = make_key_ref(key, 1); 651 key_ref = make_key_ref(key, 1);
634 break; 652 break;
635 653
636 case KEY_SPEC_USER_SESSION_KEYRING: 654 case KEY_SPEC_USER_SESSION_KEYRING:
655 if (!context->user->session_keyring) {
656 ret = install_user_keyrings(context);
657 if (ret < 0)
658 goto error;
659 }
660
637 key = context->user->session_keyring; 661 key = context->user->session_keyring;
638 atomic_inc(&key->usage); 662 atomic_inc(&key->usage);
639 key_ref = make_key_ref(key, 1); 663 key_ref = make_key_ref(key, 1);
@@ -744,7 +768,7 @@ long join_session_keyring(const char *name)
744 mutex_lock(&key_session_mutex); 768 mutex_lock(&key_session_mutex);
745 769
746 /* look for an existing keyring of this name */ 770 /* look for an existing keyring of this name */
747 keyring = find_keyring_by_name(name, 0); 771 keyring = find_keyring_by_name(name, false);
748 if (PTR_ERR(keyring) == -ENOKEY) { 772 if (PTR_ERR(keyring) == -ENOKEY) {
749 /* not found - try and create a new one */ 773 /* not found - try and create a new one */
750 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 774 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk,
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 5ecc5057fb54..ba32ca6469bd 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -16,6 +16,7 @@
16#include <linux/kmod.h> 16#include <linux/kmod.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/keyctl.h> 18#include <linux/keyctl.h>
19#include <linux/slab.h>
19#include "internal.h" 20#include "internal.h"
20 21
21/* 22/*
@@ -161,21 +162,22 @@ error_alloc:
161 * call out to userspace for key construction 162 * call out to userspace for key construction
162 * - we ignore program failure and go on key status instead 163 * - we ignore program failure and go on key status instead
163 */ 164 */
164static int construct_key(struct key *key, const char *callout_info, void *aux) 165static int construct_key(struct key *key, const void *callout_info,
166 size_t callout_len, void *aux)
165{ 167{
166 struct key_construction *cons; 168 struct key_construction *cons;
167 request_key_actor_t actor; 169 request_key_actor_t actor;
168 struct key *authkey; 170 struct key *authkey;
169 int ret; 171 int ret;
170 172
171 kenter("%d,%s,%p", key->serial, callout_info, aux); 173 kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
172 174
173 cons = kmalloc(sizeof(*cons), GFP_KERNEL); 175 cons = kmalloc(sizeof(*cons), GFP_KERNEL);
174 if (!cons) 176 if (!cons)
175 return -ENOMEM; 177 return -ENOMEM;
176 178
177 /* allocate an authorisation key */ 179 /* allocate an authorisation key */
178 authkey = request_key_auth_new(key, callout_info); 180 authkey = request_key_auth_new(key, callout_info, callout_len);
179 if (IS_ERR(authkey)) { 181 if (IS_ERR(authkey)) {
180 kfree(cons); 182 kfree(cons);
181 ret = PTR_ERR(authkey); 183 ret = PTR_ERR(authkey);
@@ -331,6 +333,7 @@ alloc_failed:
331static struct key *construct_key_and_link(struct key_type *type, 333static struct key *construct_key_and_link(struct key_type *type,
332 const char *description, 334 const char *description,
333 const char *callout_info, 335 const char *callout_info,
336 size_t callout_len,
334 void *aux, 337 void *aux,
335 struct key *dest_keyring, 338 struct key *dest_keyring,
336 unsigned long flags) 339 unsigned long flags)
@@ -348,7 +351,7 @@ static struct key *construct_key_and_link(struct key_type *type,
348 key_user_put(user); 351 key_user_put(user);
349 352
350 if (ret == 0) { 353 if (ret == 0) {
351 ret = construct_key(key, callout_info, aux); 354 ret = construct_key(key, callout_info, callout_len, aux);
352 if (ret < 0) 355 if (ret < 0)
353 goto construction_failed; 356 goto construction_failed;
354 } 357 }
@@ -370,7 +373,8 @@ construction_failed:
370 */ 373 */
371struct key *request_key_and_link(struct key_type *type, 374struct key *request_key_and_link(struct key_type *type,
372 const char *description, 375 const char *description,
373 const char *callout_info, 376 const void *callout_info,
377 size_t callout_len,
374 void *aux, 378 void *aux,
375 struct key *dest_keyring, 379 struct key *dest_keyring,
376 unsigned long flags) 380 unsigned long flags)
@@ -378,8 +382,8 @@ struct key *request_key_and_link(struct key_type *type,
378 struct key *key; 382 struct key *key;
379 key_ref_t key_ref; 383 key_ref_t key_ref;
380 384
381 kenter("%s,%s,%s,%p,%p,%lx", 385 kenter("%s,%s,%p,%zu,%p,%p,%lx",
382 type->name, description, callout_info, aux, 386 type->name, description, callout_info, callout_len, aux,
383 dest_keyring, flags); 387 dest_keyring, flags);
384 388
385 /* search all the process keyrings for a key */ 389 /* search all the process keyrings for a key */
@@ -398,7 +402,8 @@ struct key *request_key_and_link(struct key_type *type,
398 goto error; 402 goto error;
399 403
400 key = construct_key_and_link(type, description, callout_info, 404 key = construct_key_and_link(type, description, callout_info,
401 aux, dest_keyring, flags); 405 callout_len, aux, dest_keyring,
406 flags);
402 } 407 }
403 408
404error: 409error:
@@ -434,10 +439,13 @@ struct key *request_key(struct key_type *type,
434 const char *callout_info) 439 const char *callout_info)
435{ 440{
436 struct key *key; 441 struct key *key;
442 size_t callout_len = 0;
437 int ret; 443 int ret;
438 444
439 key = request_key_and_link(type, description, callout_info, NULL, 445 if (callout_info)
440 NULL, KEY_ALLOC_IN_QUOTA); 446 callout_len = strlen(callout_info);
447 key = request_key_and_link(type, description, callout_info, callout_len,
448 NULL, NULL, KEY_ALLOC_IN_QUOTA);
441 if (!IS_ERR(key)) { 449 if (!IS_ERR(key)) {
442 ret = wait_for_key_construction(key, false); 450 ret = wait_for_key_construction(key, false);
443 if (ret < 0) { 451 if (ret < 0) {
@@ -458,14 +466,15 @@ EXPORT_SYMBOL(request_key);
458 */ 466 */
459struct key *request_key_with_auxdata(struct key_type *type, 467struct key *request_key_with_auxdata(struct key_type *type,
460 const char *description, 468 const char *description,
461 const char *callout_info, 469 const void *callout_info,
470 size_t callout_len,
462 void *aux) 471 void *aux)
463{ 472{
464 struct key *key; 473 struct key *key;
465 int ret; 474 int ret;
466 475
467 key = request_key_and_link(type, description, callout_info, aux, 476 key = request_key_and_link(type, description, callout_info, callout_len,
468 NULL, KEY_ALLOC_IN_QUOTA); 477 aux, NULL, KEY_ALLOC_IN_QUOTA);
469 if (!IS_ERR(key)) { 478 if (!IS_ERR(key)) {
470 ret = wait_for_key_construction(key, false); 479 ret = wait_for_key_construction(key, false);
471 if (ret < 0) { 480 if (ret < 0) {
@@ -485,10 +494,12 @@ EXPORT_SYMBOL(request_key_with_auxdata);
485 */ 494 */
486struct key *request_key_async(struct key_type *type, 495struct key *request_key_async(struct key_type *type,
487 const char *description, 496 const char *description,
488 const char *callout_info) 497 const void *callout_info,
498 size_t callout_len)
489{ 499{
490 return request_key_and_link(type, description, callout_info, NULL, 500 return request_key_and_link(type, description, callout_info,
491 NULL, KEY_ALLOC_IN_QUOTA); 501 callout_len, NULL, NULL,
502 KEY_ALLOC_IN_QUOTA);
492} 503}
493EXPORT_SYMBOL(request_key_async); 504EXPORT_SYMBOL(request_key_async);
494 505
@@ -500,10 +511,11 @@ EXPORT_SYMBOL(request_key_async);
500 */ 511 */
501struct key *request_key_async_with_auxdata(struct key_type *type, 512struct key *request_key_async_with_auxdata(struct key_type *type,
502 const char *description, 513 const char *description,
503 const char *callout_info, 514 const void *callout_info,
515 size_t callout_len,
504 void *aux) 516 void *aux)
505{ 517{
506 return request_key_and_link(type, description, callout_info, aux, 518 return request_key_and_link(type, description, callout_info,
507 NULL, KEY_ALLOC_IN_QUOTA); 519 callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
508} 520}
509EXPORT_SYMBOL(request_key_async_with_auxdata); 521EXPORT_SYMBOL(request_key_async_with_auxdata);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index e42b5252486f..bd237b0a6331 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -15,6 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <linux/slab.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19#include "internal.h" 20#include "internal.h"
20 21
@@ -61,7 +62,7 @@ static void request_key_auth_describe(const struct key *key,
61 62
62 seq_puts(m, "key:"); 63 seq_puts(m, "key:");
63 seq_puts(m, key->description); 64 seq_puts(m, key->description);
64 seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info)); 65 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
65 66
66} /* end request_key_auth_describe() */ 67} /* end request_key_auth_describe() */
67 68
@@ -77,7 +78,7 @@ static long request_key_auth_read(const struct key *key,
77 size_t datalen; 78 size_t datalen;
78 long ret; 79 long ret;
79 80
80 datalen = strlen(rka->callout_info); 81 datalen = rka->callout_len;
81 ret = datalen; 82 ret = datalen;
82 83
83 /* we can return the data as is */ 84 /* we can return the data as is */
@@ -137,7 +138,8 @@ static void request_key_auth_destroy(struct key *key)
137 * create an authorisation token for /sbin/request-key or whoever to gain 138 * create an authorisation token for /sbin/request-key or whoever to gain
138 * access to the caller's security data 139 * access to the caller's security data
139 */ 140 */
140struct key *request_key_auth_new(struct key *target, const char *callout_info) 141struct key *request_key_auth_new(struct key *target, const void *callout_info,
142 size_t callout_len)
141{ 143{
142 struct request_key_auth *rka, *irka; 144 struct request_key_auth *rka, *irka;
143 struct key *authkey = NULL; 145 struct key *authkey = NULL;
@@ -152,7 +154,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
152 kleave(" = -ENOMEM"); 154 kleave(" = -ENOMEM");
153 return ERR_PTR(-ENOMEM); 155 return ERR_PTR(-ENOMEM);
154 } 156 }
155 rka->callout_info = kmalloc(strlen(callout_info) + 1, GFP_KERNEL); 157 rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
156 if (!rka->callout_info) { 158 if (!rka->callout_info) {
157 kleave(" = -ENOMEM"); 159 kleave(" = -ENOMEM");
158 kfree(rka); 160 kfree(rka);
@@ -186,7 +188,8 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
186 } 188 }
187 189
188 rka->target_key = key_get(target); 190 rka->target_key = key_get(target);
189 strcpy(rka->callout_info, callout_info); 191 memcpy(rka->callout_info, callout_info, callout_len);
192 rka->callout_len = callout_len;
190 193
191 /* allocate the auth key */ 194 /* allocate the auth key */
192 sprintf(desc, "%x", target->serial); 195 sprintf(desc, "%x", target->serial);
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c
new file mode 100644
index 000000000000..b611d493c2d8
--- /dev/null
+++ b/security/keys/sysctl.c
@@ -0,0 +1,50 @@
1/* Key management controls
2 *
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/key.h>
13#include <linux/sysctl.h>
14#include "internal.h"
15
16ctl_table key_sysctls[] = {
17 {
18 .ctl_name = CTL_UNNUMBERED,
19 .procname = "maxkeys",
20 .data = &key_quota_maxkeys,
21 .maxlen = sizeof(unsigned),
22 .mode = 0644,
23 .proc_handler = &proc_dointvec,
24 },
25 {
26 .ctl_name = CTL_UNNUMBERED,
27 .procname = "maxbytes",
28 .data = &key_quota_maxbytes,
29 .maxlen = sizeof(unsigned),
30 .mode = 0644,
31 .proc_handler = &proc_dointvec,
32 },
33 {
34 .ctl_name = CTL_UNNUMBERED,
35 .procname = "root_maxkeys",
36 .data = &key_quota_root_maxkeys,
37 .maxlen = sizeof(unsigned),
38 .mode = 0644,
39 .proc_handler = &proc_dointvec,
40 },
41 {
42 .ctl_name = CTL_UNNUMBERED,
43 .procname = "root_maxbytes",
44 .data = &key_quota_root_maxbytes,
45 .maxlen = sizeof(unsigned),
46 .mode = 0644,
47 .proc_handler = &proc_dointvec,
48 },
49 { .ctl_name = 0 }
50};
diff --git a/security/root_plug.c b/security/root_plug.c
index 6112d1404c81..a41cf42a4fa0 100644
--- a/security/root_plug.c
+++ b/security/root_plug.c
@@ -86,6 +86,7 @@ static struct security_operations rootplug_security_ops = {
86 86
87 .task_post_setuid = cap_task_post_setuid, 87 .task_post_setuid = cap_task_post_setuid,
88 .task_reparent_to_init = cap_task_reparent_to_init, 88 .task_reparent_to_init = cap_task_reparent_to_init,
89 .task_prctl = cap_task_prctl,
89 90
90 .bprm_check_security = rootplug_bprm_check_security, 91 .bprm_check_security = rootplug_bprm_check_security,
91}; 92};
diff --git a/security/security.c b/security/security.c
index 8a285c7b9962..8e64a29dc55d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -491,23 +491,23 @@ void security_inode_delete(struct inode *inode)
491 security_ops->inode_delete(inode); 491 security_ops->inode_delete(inode);
492} 492}
493 493
494int security_inode_setxattr(struct dentry *dentry, char *name, 494int security_inode_setxattr(struct dentry *dentry, const char *name,
495 void *value, size_t size, int flags) 495 const void *value, size_t size, int flags)
496{ 496{
497 if (unlikely(IS_PRIVATE(dentry->d_inode))) 497 if (unlikely(IS_PRIVATE(dentry->d_inode)))
498 return 0; 498 return 0;
499 return security_ops->inode_setxattr(dentry, name, value, size, flags); 499 return security_ops->inode_setxattr(dentry, name, value, size, flags);
500} 500}
501 501
502void security_inode_post_setxattr(struct dentry *dentry, char *name, 502void security_inode_post_setxattr(struct dentry *dentry, const char *name,
503 void *value, size_t size, int flags) 503 const void *value, size_t size, int flags)
504{ 504{
505 if (unlikely(IS_PRIVATE(dentry->d_inode))) 505 if (unlikely(IS_PRIVATE(dentry->d_inode)))
506 return; 506 return;
507 security_ops->inode_post_setxattr(dentry, name, value, size, flags); 507 security_ops->inode_post_setxattr(dentry, name, value, size, flags);
508} 508}
509 509
510int security_inode_getxattr(struct dentry *dentry, char *name) 510int security_inode_getxattr(struct dentry *dentry, const char *name)
511{ 511{
512 if (unlikely(IS_PRIVATE(dentry->d_inode))) 512 if (unlikely(IS_PRIVATE(dentry->d_inode)))
513 return 0; 513 return 0;
@@ -521,7 +521,7 @@ int security_inode_listxattr(struct dentry *dentry)
521 return security_ops->inode_listxattr(dentry); 521 return security_ops->inode_listxattr(dentry);
522} 522}
523 523
524int security_inode_removexattr(struct dentry *dentry, char *name) 524int security_inode_removexattr(struct dentry *dentry, const char *name)
525{ 525{
526 if (unlikely(IS_PRIVATE(dentry->d_inode))) 526 if (unlikely(IS_PRIVATE(dentry->d_inode)))
527 return 0; 527 return 0;
@@ -733,9 +733,9 @@ int security_task_wait(struct task_struct *p)
733} 733}
734 734
735int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, 735int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
736 unsigned long arg4, unsigned long arg5) 736 unsigned long arg4, unsigned long arg5, long *rc_p)
737{ 737{
738 return security_ops->task_prctl(option, arg2, arg3, arg4, arg5); 738 return security_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p);
739} 739}
740 740
741void security_task_reparent_to_init(struct task_struct *p) 741void security_task_reparent_to_init(struct task_struct *p)
@@ -1156,6 +1156,11 @@ int security_key_permission(key_ref_t key_ref,
1156 return security_ops->key_permission(key_ref, context, perm); 1156 return security_ops->key_permission(key_ref, context, perm);
1157} 1157}
1158 1158
1159int security_key_getsecurity(struct key *key, char **_buffer)
1160{
1161 return security_ops->key_getsecurity(key, _buffer);
1162}
1163
1159#endif /* CONFIG_KEYS */ 1164#endif /* CONFIG_KEYS */
1160 1165
1161#ifdef CONFIG_AUDIT 1166#ifdef CONFIG_AUDIT
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 308e2cf17d75..4e4de98941ae 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2619,7 +2619,7 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2619 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); 2619 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
2620} 2620}
2621 2621
2622static int selinux_inode_setotherxattr(struct dentry *dentry, char *name) 2622static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2623{ 2623{
2624 if (!strncmp(name, XATTR_SECURITY_PREFIX, 2624 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2625 sizeof XATTR_SECURITY_PREFIX - 1)) { 2625 sizeof XATTR_SECURITY_PREFIX - 1)) {
@@ -2638,7 +2638,8 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, char *name)
2638 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); 2638 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2639} 2639}
2640 2640
2641static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) 2641static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2642 const void *value, size_t size, int flags)
2642{ 2643{
2643 struct task_security_struct *tsec = current->security; 2644 struct task_security_struct *tsec = current->security;
2644 struct inode *inode = dentry->d_inode; 2645 struct inode *inode = dentry->d_inode;
@@ -2687,8 +2688,9 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
2687 &ad); 2688 &ad);
2688} 2689}
2689 2690
2690static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, 2691static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2691 void *value, size_t size, int flags) 2692 const void *value, size_t size,
2693 int flags)
2692{ 2694{
2693 struct inode *inode = dentry->d_inode; 2695 struct inode *inode = dentry->d_inode;
2694 struct inode_security_struct *isec = inode->i_security; 2696 struct inode_security_struct *isec = inode->i_security;
@@ -2711,7 +2713,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
2711 return; 2713 return;
2712} 2714}
2713 2715
2714static int selinux_inode_getxattr(struct dentry *dentry, char *name) 2716static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2715{ 2717{
2716 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2718 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2717} 2719}
@@ -2721,7 +2723,7 @@ static int selinux_inode_listxattr(struct dentry *dentry)
2721 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2723 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2722} 2724}
2723 2725
2724static int selinux_inode_removexattr(struct dentry *dentry, char *name) 2726static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
2725{ 2727{
2726 if (strcmp(name, XATTR_NAME_SELINUX)) 2728 if (strcmp(name, XATTR_NAME_SELINUX))
2727 return selinux_inode_setotherxattr(dentry, name); 2729 return selinux_inode_setotherxattr(dentry, name);
@@ -3303,12 +3305,13 @@ static int selinux_task_prctl(int option,
3303 unsigned long arg2, 3305 unsigned long arg2,
3304 unsigned long arg3, 3306 unsigned long arg3,
3305 unsigned long arg4, 3307 unsigned long arg4,
3306 unsigned long arg5) 3308 unsigned long arg5,
3309 long *rc_p)
3307{ 3310{
3308 /* The current prctl operations do not appear to require 3311 /* The current prctl operations do not appear to require
3309 any SELinux controls since they merely observe or modify 3312 any SELinux controls since they merely observe or modify
3310 the state of the current process. */ 3313 the state of the current process. */
3311 return 0; 3314 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p);
3312} 3315}
3313 3316
3314static int selinux_task_wait(struct task_struct *p) 3317static int selinux_task_wait(struct task_struct *p)
@@ -5297,6 +5300,20 @@ static int selinux_key_permission(key_ref_t key_ref,
5297 SECCLASS_KEY, perm, NULL); 5300 SECCLASS_KEY, perm, NULL);
5298} 5301}
5299 5302
5303static int selinux_key_getsecurity(struct key *key, char **_buffer)
5304{
5305 struct key_security_struct *ksec = key->security;
5306 char *context = NULL;
5307 unsigned len;
5308 int rc;
5309
5310 rc = security_sid_to_context(ksec->sid, &context, &len);
5311 if (!rc)
5312 rc = len;
5313 *_buffer = context;
5314 return rc;
5315}
5316
5300#endif 5317#endif
5301 5318
5302static struct security_operations selinux_ops = { 5319static struct security_operations selinux_ops = {
@@ -5485,6 +5502,7 @@ static struct security_operations selinux_ops = {
5485 .key_alloc = selinux_key_alloc, 5502 .key_alloc = selinux_key_alloc,
5486 .key_free = selinux_key_free, 5503 .key_free = selinux_key_free,
5487 .key_permission = selinux_key_permission, 5504 .key_permission = selinux_key_permission,
5505 .key_getsecurity = selinux_key_getsecurity,
5488#endif 5506#endif
5489 5507
5490#ifdef CONFIG_AUDIT 5508#ifdef CONFIG_AUDIT
@@ -5533,14 +5551,6 @@ static __init int selinux_init(void)
5533 else 5551 else
5534 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); 5552 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
5535 5553
5536#ifdef CONFIG_KEYS
5537 /* Add security information to initial keyrings */
5538 selinux_key_alloc(&root_user_keyring, current,
5539 KEY_ALLOC_NOT_IN_QUOTA);
5540 selinux_key_alloc(&root_session_keyring, current,
5541 KEY_ALLOC_NOT_IN_QUOTA);
5542#endif
5543
5544 return 0; 5554 return 0;
5545} 5555}
5546 5556
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h
index ff869e8b6f4a..c0d314d9f8e1 100644
--- a/security/selinux/include/avc_ss.h
+++ b/security/selinux/include/avc_ss.h
@@ -10,22 +10,19 @@
10 10
11int avc_ss_reset(u32 seqno); 11int avc_ss_reset(u32 seqno);
12 12
13struct av_perm_to_string 13struct av_perm_to_string {
14{
15 u16 tclass; 14 u16 tclass;
16 u32 value; 15 u32 value;
17 const char *name; 16 const char *name;
18}; 17};
19 18
20struct av_inherit 19struct av_inherit {
21{
22 u16 tclass; 20 u16 tclass;
23 const char **common_pts; 21 const char **common_pts;
24 u32 common_base; 22 u32 common_base;
25}; 23};
26 24
27struct selinux_class_perm 25struct selinux_class_perm {
28{
29 const struct av_perm_to_string *av_perm_to_string; 26 const struct av_perm_to_string *av_perm_to_string;
30 u32 av_pts_len; 27 u32 av_pts_len;
31 const char **class_to_string; 28 const char **class_to_string;
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 9a9e7cd9a379..487a7d81fe20 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -64,7 +64,7 @@ static inline void selinux_netlbl_cache_invalidate(void)
64} 64}
65 65
66static inline void selinux_netlbl_sk_security_reset( 66static inline void selinux_netlbl_sk_security_reset(
67 struct sk_security_struct *ssec, 67 struct sk_security_struct *ssec,
68 int family) 68 int family)
69{ 69{
70 return; 70 return;
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 300b61bad7b3..032c2357dad1 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -4,16 +4,16 @@
4 * This file contains the SELinux security data structures for kernel objects. 4 * This file contains the SELinux security data structures for kernel objects.
5 * 5 *
6 * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil> 6 * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil>
7 * Chris Vance, <cvance@nai.com> 7 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com> 8 * Wayne Salamon, <wsalamon@nai.com>
9 * James Morris <jmorris@redhat.com> 9 * James Morris <jmorris@redhat.com>
10 * 10 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc. 11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2, 15 * it under the terms of the GNU General Public License version 2,
16 * as published by the Free Software Foundation. 16 * as published by the Free Software Foundation.
17 */ 17 */
18#ifndef _SELINUX_OBJSEC_H_ 18#ifndef _SELINUX_OBJSEC_H_
19#define _SELINUX_OBJSEC_H_ 19#define _SELINUX_OBJSEC_H_
@@ -28,58 +28,58 @@
28#include "avc.h" 28#include "avc.h"
29 29
30struct task_security_struct { 30struct task_security_struct {
31 u32 osid; /* SID prior to last execve */ 31 u32 osid; /* SID prior to last execve */
32 u32 sid; /* current SID */ 32 u32 sid; /* current SID */
33 u32 exec_sid; /* exec SID */ 33 u32 exec_sid; /* exec SID */
34 u32 create_sid; /* fscreate SID */ 34 u32 create_sid; /* fscreate SID */
35 u32 keycreate_sid; /* keycreate SID */ 35 u32 keycreate_sid; /* keycreate SID */
36 u32 sockcreate_sid; /* fscreate SID */ 36 u32 sockcreate_sid; /* fscreate SID */
37}; 37};
38 38
39struct inode_security_struct { 39struct inode_security_struct {
40 struct inode *inode; /* back pointer to inode object */ 40 struct inode *inode; /* back pointer to inode object */
41 struct list_head list; /* list of inode_security_struct */ 41 struct list_head list; /* list of inode_security_struct */
42 u32 task_sid; /* SID of creating task */ 42 u32 task_sid; /* SID of creating task */
43 u32 sid; /* SID of this object */ 43 u32 sid; /* SID of this object */
44 u16 sclass; /* security class of this object */ 44 u16 sclass; /* security class of this object */
45 unsigned char initialized; /* initialization flag */ 45 unsigned char initialized; /* initialization flag */
46 struct mutex lock; 46 struct mutex lock;
47 unsigned char inherit; /* inherit SID from parent entry */ 47 unsigned char inherit; /* inherit SID from parent entry */
48}; 48};
49 49
50struct file_security_struct { 50struct file_security_struct {
51 u32 sid; /* SID of open file description */ 51 u32 sid; /* SID of open file description */
52 u32 fown_sid; /* SID of file owner (for SIGIO) */ 52 u32 fown_sid; /* SID of file owner (for SIGIO) */
53 u32 isid; /* SID of inode at the time of file open */ 53 u32 isid; /* SID of inode at the time of file open */
54 u32 pseqno; /* Policy seqno at the time of file open */ 54 u32 pseqno; /* Policy seqno at the time of file open */
55}; 55};
56 56
57struct superblock_security_struct { 57struct superblock_security_struct {
58 struct super_block *sb; /* back pointer to sb object */ 58 struct super_block *sb; /* back pointer to sb object */
59 struct list_head list; /* list of superblock_security_struct */ 59 struct list_head list; /* list of superblock_security_struct */
60 u32 sid; /* SID of file system superblock */ 60 u32 sid; /* SID of file system superblock */
61 u32 def_sid; /* default SID for labeling */ 61 u32 def_sid; /* default SID for labeling */
62 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ 62 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
63 unsigned int behavior; /* labeling behavior */ 63 unsigned int behavior; /* labeling behavior */
64 unsigned char initialized; /* initialization flag */ 64 unsigned char initialized; /* initialization flag */
65 unsigned char flags; /* which mount options were specified */ 65 unsigned char flags; /* which mount options were specified */
66 unsigned char proc; /* proc fs */ 66 unsigned char proc; /* proc fs */
67 struct mutex lock; 67 struct mutex lock;
68 struct list_head isec_head; 68 struct list_head isec_head;
69 spinlock_t isec_lock; 69 spinlock_t isec_lock;
70}; 70};
71 71
72struct msg_security_struct { 72struct msg_security_struct {
73 u32 sid; /* SID of message */ 73 u32 sid; /* SID of message */
74}; 74};
75 75
76struct ipc_security_struct { 76struct ipc_security_struct {
77 u16 sclass; /* security class of this object */ 77 u16 sclass; /* security class of this object */
78 u32 sid; /* SID of IPC resource */ 78 u32 sid; /* SID of IPC resource */
79}; 79};
80 80
81struct bprm_security_struct { 81struct bprm_security_struct {
82 u32 sid; /* SID for transformed process */ 82 u32 sid; /* SID for transformed process */
83 unsigned char set; 83 unsigned char set;
84 84
85 /* 85 /*
@@ -123,7 +123,7 @@ struct sk_security_struct {
123}; 123};
124 124
125struct key_security_struct { 125struct key_security_struct {
126 u32 sid; /* SID of key */ 126 u32 sid; /* SID of key */
127}; 127};
128 128
129extern unsigned int selinux_checkreqprot; 129extern unsigned int selinux_checkreqprot;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 1904c462a605..cdb14add27d2 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -62,7 +62,7 @@ enum {
62extern int selinux_policycap_netpeer; 62extern int selinux_policycap_netpeer;
63extern int selinux_policycap_openperm; 63extern int selinux_policycap_openperm;
64 64
65int security_load_policy(void * data, size_t len); 65int security_load_policy(void *data, size_t len);
66 66
67int security_policycap_supported(unsigned int req_cap); 67int security_policycap_supported(unsigned int req_cap);
68 68
@@ -93,7 +93,7 @@ int security_change_sid(u32 ssid, u32 tsid,
93int security_sid_to_context(u32 sid, char **scontext, 93int security_sid_to_context(u32 sid, char **scontext,
94 u32 *scontext_len); 94 u32 *scontext_len);
95 95
96int security_context_to_sid(char *scontext, u32 scontext_len, 96int security_context_to_sid(const char *scontext, u32 scontext_len,
97 u32 *out_sid); 97 u32 *out_sid);
98 98
99int security_context_to_sid_default(char *scontext, u32 scontext_len, 99int security_context_to_sid_default(char *scontext, u32 scontext_len,
@@ -110,7 +110,7 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen,
110 u32 *out_sid); 110 u32 *out_sid);
111 111
112int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 112int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
113 u16 tclass); 113 u16 tclass);
114 114
115int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); 115int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
116 116
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 2edc4c5e0c61..b6ccd09379f1 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -40,11 +40,17 @@
40#include <net/ipv6.h> 40#include <net/ipv6.h>
41#include <asm/bug.h> 41#include <asm/bug.h>
42 42
43#include "netnode.h"
43#include "objsec.h" 44#include "objsec.h"
44 45
45#define SEL_NETNODE_HASH_SIZE 256 46#define SEL_NETNODE_HASH_SIZE 256
46#define SEL_NETNODE_HASH_BKT_LIMIT 16 47#define SEL_NETNODE_HASH_BKT_LIMIT 16
47 48
49struct sel_netnode_bkt {
50 unsigned int size;
51 struct list_head list;
52};
53
48struct sel_netnode { 54struct sel_netnode {
49 struct netnode_security_struct nsec; 55 struct netnode_security_struct nsec;
50 56
@@ -60,7 +66,7 @@ struct sel_netnode {
60 66
61static LIST_HEAD(sel_netnode_list); 67static LIST_HEAD(sel_netnode_list);
62static DEFINE_SPINLOCK(sel_netnode_lock); 68static DEFINE_SPINLOCK(sel_netnode_lock);
63static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; 69static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
64 70
65/** 71/**
66 * sel_netnode_free - Frees a node entry 72 * sel_netnode_free - Frees a node entry
@@ -87,7 +93,7 @@ static void sel_netnode_free(struct rcu_head *p)
87 * the bucket number for the given IP address. 93 * the bucket number for the given IP address.
88 * 94 *
89 */ 95 */
90static u32 sel_netnode_hashfn_ipv4(__be32 addr) 96static unsigned int sel_netnode_hashfn_ipv4(__be32 addr)
91{ 97{
92 /* at some point we should determine if the mismatch in byte order 98 /* at some point we should determine if the mismatch in byte order
93 * affects the hash function dramatically */ 99 * affects the hash function dramatically */
@@ -103,7 +109,7 @@ static u32 sel_netnode_hashfn_ipv4(__be32 addr)
103 * the bucket number for the given IP address. 109 * the bucket number for the given IP address.
104 * 110 *
105 */ 111 */
106static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) 112static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
107{ 113{
108 /* just hash the least significant 32 bits to keep things fast (they 114 /* just hash the least significant 32 bits to keep things fast (they
109 * are the most likely to be different anyway), we can revisit this 115 * are the most likely to be different anyway), we can revisit this
@@ -123,7 +129,7 @@ static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
123 */ 129 */
124static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) 130static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
125{ 131{
126 u32 idx; 132 unsigned int idx;
127 struct sel_netnode *node; 133 struct sel_netnode *node;
128 134
129 switch (family) { 135 switch (family) {
@@ -137,7 +143,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
137 BUG(); 143 BUG();
138 } 144 }
139 145
140 list_for_each_entry_rcu(node, &sel_netnode_hash[idx], list) 146 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
141 if (node->nsec.family == family) 147 if (node->nsec.family == family)
142 switch (family) { 148 switch (family) {
143 case PF_INET: 149 case PF_INET:
@@ -159,15 +165,12 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
159 * @node: the new node record 165 * @node: the new node record
160 * 166 *
161 * Description: 167 * Description:
162 * Add a new node record to the network address hash table. Returns zero on 168 * Add a new node record to the network address hash table.
163 * success, negative values on failure.
164 * 169 *
165 */ 170 */
166static int sel_netnode_insert(struct sel_netnode *node) 171static void sel_netnode_insert(struct sel_netnode *node)
167{ 172{
168 u32 idx; 173 unsigned int idx;
169 u32 count = 0;
170 struct sel_netnode *iter;
171 174
172 switch (node->nsec.family) { 175 switch (node->nsec.family) {
173 case PF_INET: 176 case PF_INET:
@@ -179,32 +182,21 @@ static int sel_netnode_insert(struct sel_netnode *node)
179 default: 182 default:
180 BUG(); 183 BUG();
181 } 184 }
182 list_add_rcu(&node->list, &sel_netnode_hash[idx]); 185
186 INIT_RCU_HEAD(&node->rcu);
183 187
184 /* we need to impose a limit on the growth of the hash table so check 188 /* we need to impose a limit on the growth of the hash table so check
185 * this bucket to make sure it is within the specified bounds */ 189 * this bucket to make sure it is within the specified bounds */
186 list_for_each_entry(iter, &sel_netnode_hash[idx], list) 190 list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
187 if (++count > SEL_NETNODE_HASH_BKT_LIMIT) { 191 if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
188 list_del_rcu(&iter->list); 192 struct sel_netnode *tail;
189 call_rcu(&iter->rcu, sel_netnode_free); 193 tail = list_entry(
190 break; 194 rcu_dereference(sel_netnode_hash[idx].list.prev),
191 } 195 struct sel_netnode, list);
192 196 list_del_rcu(&tail->list);
193 return 0; 197 call_rcu(&tail->rcu, sel_netnode_free);
194} 198 } else
195 199 sel_netnode_hash[idx].size++;
196/**
197 * sel_netnode_destroy - Remove a node record from the table
198 * @node: the existing node record
199 *
200 * Description:
201 * Remove an existing node record from the network address table.
202 *
203 */
204static void sel_netnode_destroy(struct sel_netnode *node)
205{
206 list_del_rcu(&node->list);
207 call_rcu(&node->rcu, sel_netnode_free);
208} 200}
209 201
210/** 202/**
@@ -222,7 +214,7 @@ static void sel_netnode_destroy(struct sel_netnode *node)
222 */ 214 */
223static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) 215static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
224{ 216{
225 int ret; 217 int ret = -ENOMEM;
226 struct sel_netnode *node; 218 struct sel_netnode *node;
227 struct sel_netnode *new = NULL; 219 struct sel_netnode *new = NULL;
228 220
@@ -230,25 +222,21 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
230 node = sel_netnode_find(addr, family); 222 node = sel_netnode_find(addr, family);
231 if (node != NULL) { 223 if (node != NULL) {
232 *sid = node->nsec.sid; 224 *sid = node->nsec.sid;
233 ret = 0; 225 spin_unlock_bh(&sel_netnode_lock);
234 goto out; 226 return 0;
235 } 227 }
236 new = kzalloc(sizeof(*new), GFP_ATOMIC); 228 new = kzalloc(sizeof(*new), GFP_ATOMIC);
237 if (new == NULL) { 229 if (new == NULL)
238 ret = -ENOMEM;
239 goto out; 230 goto out;
240 }
241 switch (family) { 231 switch (family) {
242 case PF_INET: 232 case PF_INET:
243 ret = security_node_sid(PF_INET, 233 ret = security_node_sid(PF_INET,
244 addr, sizeof(struct in_addr), 234 addr, sizeof(struct in_addr), sid);
245 &new->nsec.sid);
246 new->nsec.addr.ipv4 = *(__be32 *)addr; 235 new->nsec.addr.ipv4 = *(__be32 *)addr;
247 break; 236 break;
248 case PF_INET6: 237 case PF_INET6:
249 ret = security_node_sid(PF_INET6, 238 ret = security_node_sid(PF_INET6,
250 addr, sizeof(struct in6_addr), 239 addr, sizeof(struct in6_addr), sid);
251 &new->nsec.sid);
252 ipv6_addr_copy(&new->nsec.addr.ipv6, addr); 240 ipv6_addr_copy(&new->nsec.addr.ipv6, addr);
253 break; 241 break;
254 default: 242 default:
@@ -256,11 +244,10 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
256 } 244 }
257 if (ret != 0) 245 if (ret != 0)
258 goto out; 246 goto out;
247
259 new->nsec.family = family; 248 new->nsec.family = family;
260 ret = sel_netnode_insert(new); 249 new->nsec.sid = *sid;
261 if (ret != 0) 250 sel_netnode_insert(new);
262 goto out;
263 *sid = new->nsec.sid;
264 251
265out: 252out:
266 spin_unlock_bh(&sel_netnode_lock); 253 spin_unlock_bh(&sel_netnode_lock);
@@ -312,13 +299,18 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
312 */ 299 */
313static void sel_netnode_flush(void) 300static void sel_netnode_flush(void)
314{ 301{
315 u32 idx; 302 unsigned int idx;
316 struct sel_netnode *node; 303 struct sel_netnode *node, *node_tmp;
317 304
318 spin_lock_bh(&sel_netnode_lock); 305 spin_lock_bh(&sel_netnode_lock);
319 for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) 306 for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) {
320 list_for_each_entry(node, &sel_netnode_hash[idx], list) 307 list_for_each_entry_safe(node, node_tmp,
321 sel_netnode_destroy(node); 308 &sel_netnode_hash[idx].list, list) {
309 list_del_rcu(&node->list);
310 call_rcu(&node->rcu, sel_netnode_free);
311 }
312 sel_netnode_hash[idx].size = 0;
313 }
322 spin_unlock_bh(&sel_netnode_lock); 314 spin_unlock_bh(&sel_netnode_lock);
323} 315}
324 316
@@ -340,8 +332,10 @@ static __init int sel_netnode_init(void)
340 if (!selinux_enabled) 332 if (!selinux_enabled)
341 return 0; 333 return 0;
342 334
343 for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) 335 for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) {
344 INIT_LIST_HEAD(&sel_netnode_hash[iter]); 336 INIT_LIST_HEAD(&sel_netnode_hash[iter].list);
337 sel_netnode_hash[iter].size = 0;
338 }
345 339
346 ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, 340 ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET,
347 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); 341 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index 68ede3c498ab..90b4cff7c350 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -114,8 +114,7 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum)
114 114
115 idx = sel_netport_hashfn(pnum); 115 idx = sel_netport_hashfn(pnum);
116 list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list) 116 list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list)
117 if (port->psec.port == pnum && 117 if (port->psec.port == pnum && port->psec.protocol == protocol)
118 port->psec.protocol == protocol)
119 return port; 118 return port;
120 119
121 return NULL; 120 return NULL;
@@ -126,11 +125,10 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum)
126 * @port: the new port record 125 * @port: the new port record
127 * 126 *
128 * Description: 127 * Description:
129 * Add a new port record to the network address hash table. Returns zero on 128 * Add a new port record to the network address hash table.
130 * success, negative values on failure.
131 * 129 *
132 */ 130 */
133static int sel_netport_insert(struct sel_netport *port) 131static void sel_netport_insert(struct sel_netport *port)
134{ 132{
135 unsigned int idx; 133 unsigned int idx;
136 134
@@ -140,13 +138,13 @@ static int sel_netport_insert(struct sel_netport *port)
140 list_add_rcu(&port->list, &sel_netport_hash[idx].list); 138 list_add_rcu(&port->list, &sel_netport_hash[idx].list);
141 if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { 139 if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
142 struct sel_netport *tail; 140 struct sel_netport *tail;
143 tail = list_entry(port->list.prev, struct sel_netport, list); 141 tail = list_entry(
144 list_del_rcu(port->list.prev); 142 rcu_dereference(sel_netport_hash[idx].list.prev),
143 struct sel_netport, list);
144 list_del_rcu(&tail->list);
145 call_rcu(&tail->rcu, sel_netport_free); 145 call_rcu(&tail->rcu, sel_netport_free);
146 } else 146 } else
147 sel_netport_hash[idx].size++; 147 sel_netport_hash[idx].size++;
148
149 return 0;
150} 148}
151 149
152/** 150/**
@@ -163,7 +161,7 @@ static int sel_netport_insert(struct sel_netport *port)
163 */ 161 */
164static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) 162static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
165{ 163{
166 int ret; 164 int ret = -ENOMEM;
167 struct sel_netport *port; 165 struct sel_netport *port;
168 struct sel_netport *new = NULL; 166 struct sel_netport *new = NULL;
169 167
@@ -171,23 +169,20 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
171 port = sel_netport_find(protocol, pnum); 169 port = sel_netport_find(protocol, pnum);
172 if (port != NULL) { 170 if (port != NULL) {
173 *sid = port->psec.sid; 171 *sid = port->psec.sid;
174 ret = 0; 172 spin_unlock_bh(&sel_netport_lock);
175 goto out; 173 return 0;
176 } 174 }
177 new = kzalloc(sizeof(*new), GFP_ATOMIC); 175 new = kzalloc(sizeof(*new), GFP_ATOMIC);
178 if (new == NULL) { 176 if (new == NULL)
179 ret = -ENOMEM;
180 goto out; 177 goto out;
181 } 178 ret = security_port_sid(protocol, pnum, sid);
182 ret = security_port_sid(protocol, pnum, &new->psec.sid);
183 if (ret != 0) 179 if (ret != 0)
184 goto out; 180 goto out;
181
185 new->psec.port = pnum; 182 new->psec.port = pnum;
186 new->psec.protocol = protocol; 183 new->psec.protocol = protocol;
187 ret = sel_netport_insert(new); 184 new->psec.sid = *sid;
188 if (ret != 0) 185 sel_netport_insert(new);
189 goto out;
190 *sid = new->psec.sid;
191 186
192out: 187out:
193 spin_unlock_bh(&sel_netport_lock); 188 spin_unlock_bh(&sel_netport_lock);
@@ -239,11 +234,12 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
239static void sel_netport_flush(void) 234static void sel_netport_flush(void)
240{ 235{
241 unsigned int idx; 236 unsigned int idx;
242 struct sel_netport *port; 237 struct sel_netport *port, *port_tmp;
243 238
244 spin_lock_bh(&sel_netport_lock); 239 spin_lock_bh(&sel_netport_lock);
245 for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) { 240 for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) {
246 list_for_each_entry(port, &sel_netport_hash[idx].list, list) { 241 list_for_each_entry_safe(port, port_tmp,
242 &sel_netport_hash[idx].list, list) {
247 list_del_rcu(&port->list); 243 list_del_rcu(&port->list);
248 call_rcu(&port->rcu, sel_netport_free); 244 call_rcu(&port->rcu, sel_netport_free);
249 } 245 }
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index f3a1fc6e5d66..65b9f8366e9c 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -59,10 +59,10 @@ struct cond_node {
59 struct cond_node *next; 59 struct cond_node *next;
60}; 60};
61 61
62int cond_policydb_init(struct policydb* p); 62int cond_policydb_init(struct policydb *p);
63void cond_policydb_destroy(struct policydb* p); 63void cond_policydb_destroy(struct policydb *p);
64 64
65int cond_init_bool_indexes(struct policydb* p); 65int cond_init_bool_indexes(struct policydb *p);
66int cond_destroy_bool(void *key, void *datum, void *p); 66int cond_destroy_bool(void *key, void *datum, void *p);
67 67
68int cond_index_bool(void *key, void *datum, void *datap); 68int cond_index_bool(void *key, void *datum, void *datap);
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index 2eee0dab524d..b9a6f7fc62fc 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -84,9 +84,9 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2)
84 return 1; 84 return 1;
85 85
86 return ((c1->range.level[0].sens == c2->range.level[0].sens) && 86 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
87 ebitmap_cmp(&c1->range.level[0].cat,&c2->range.level[0].cat) && 87 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
88 (c1->range.level[1].sens == c2->range.level[1].sens) && 88 (c1->range.level[1].sens == c2->range.level[1].sens) &&
89 ebitmap_cmp(&c1->range.level[1].cat,&c2->range.level[1].cat)); 89 ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
90} 90}
91 91
92static inline void mls_context_destroy(struct context *c) 92static inline void mls_context_destroy(struct context *c)
diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h
index 7e2ff3e3c6d2..953872cd84ab 100644
--- a/security/selinux/ss/hashtab.h
+++ b/security/selinux/ss/hashtab.h
@@ -40,8 +40,8 @@ struct hashtab_info {
40 * the new hash table otherwise. 40 * the new hash table otherwise.
41 */ 41 */
42struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), 42struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key),
43 int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), 43 int (*keycmp)(struct hashtab *h, const void *key1, const void *key2),
44 u32 size); 44 u32 size);
45 45
46/* 46/*
47 * Inserts the specified (key, datum) pair into the specified hash table. 47 * Inserts the specified (key, datum) pair into the specified hash table.
@@ -49,7 +49,7 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *
49 * Returns -ENOMEM on memory allocation error, 49 * Returns -ENOMEM on memory allocation error,
50 * -EEXIST if there is already an entry with the same key, 50 * -EEXIST if there is already an entry with the same key,
51 * -EINVAL for general errors or 51 * -EINVAL for general errors or
52 * 0 otherwise. 52 0 otherwise.
53 */ 53 */
54int hashtab_insert(struct hashtab *h, void *k, void *d); 54int hashtab_insert(struct hashtab *h, void *k, void *d);
55 55
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index ab53663d9f5f..0fdf6257ef64 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -13,7 +13,7 @@
13/* 13/*
14 * Updated: Hewlett-Packard <paul.moore@hp.com> 14 * Updated: Hewlett-Packard <paul.moore@hp.com>
15 * 15 *
16 * Added support to import/export the MLS label from NetLabel 16 * Added support to import/export the MLS label from NetLabel
17 * 17 *
18 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 18 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
19 */ 19 */
@@ -31,7 +31,7 @@ int mls_range_isvalid(struct policydb *p, struct mls_range *r);
31int mls_level_isvalid(struct policydb *p, struct mls_level *l); 31int mls_level_isvalid(struct policydb *p, struct mls_level *l);
32 32
33int mls_context_to_sid(char oldc, 33int mls_context_to_sid(char oldc,
34 char **scontext, 34 char **scontext,
35 struct context *context, 35 struct context *context,
36 struct sidtab *s, 36 struct sidtab *s,
37 u32 def_sid); 37 u32 def_sid);
@@ -49,7 +49,7 @@ int mls_compute_sid(struct context *scontext,
49 struct context *newcontext); 49 struct context *newcontext);
50 50
51int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 51int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
52 struct context *usercon); 52 struct context *usercon);
53 53
54#ifdef CONFIG_NETLABEL 54#ifdef CONFIG_NETLABEL
55void mls_export_netlbl_lvl(struct context *context, 55void mls_export_netlbl_lvl(struct context *context,
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index 0c692d58d489..b6e943a21061 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -31,7 +31,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
31 return 1; 31 return 1;
32 32
33 return ((l1->sens == l2->sens) && 33 return ((l1->sens == l2->sens) &&
34 ebitmap_cmp(&l1->cat, &l2->cat)); 34 ebitmap_cmp(&l1->cat, &l2->cat));
35} 35}
36 36
37static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 37static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
@@ -40,7 +40,7 @@ static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
40 return 1; 40 return 1;
41 41
42 return ((l1->sens >= l2->sens) && 42 return ((l1->sens >= l2->sens) &&
43 ebitmap_contains(&l1->cat, &l2->cat)); 43 ebitmap_contains(&l1->cat, &l2->cat));
44} 44}
45 45
46#define mls_level_incomp(l1, l2) \ 46#define mls_level_incomp(l1, l2) \
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index ba593a3da877..4253370fda6a 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -12,12 +12,12 @@
12 * 12 *
13 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 13 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
14 * 14 *
15 * Added conditional policy language extensions 15 * Added conditional policy language extensions
16 * 16 *
17 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 17 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
18 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 18 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
19 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by 20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation, version 2. 21 * the Free Software Foundation, version 2.
22 */ 22 */
23 23
@@ -221,7 +221,7 @@ struct policydb {
221 /* type enforcement conditional access vectors and transitions */ 221 /* type enforcement conditional access vectors and transitions */
222 struct avtab te_cond_avtab; 222 struct avtab te_cond_avtab;
223 /* linked list indexing te_cond_avtab by conditional */ 223 /* linked list indexing te_cond_avtab by conditional */
224 struct cond_node* cond_list; 224 struct cond_node *cond_list;
225 225
226 /* role allows */ 226 /* role allows */
227 struct role_allow *role_allow; 227 struct role_allow *role_allow;
@@ -230,10 +230,10 @@ struct policydb {
230 TCP or UDP port numbers, network interfaces and nodes */ 230 TCP or UDP port numbers, network interfaces and nodes */
231 struct ocontext *ocontexts[OCON_NUM]; 231 struct ocontext *ocontexts[OCON_NUM];
232 232
233 /* security contexts for files in filesystems that cannot support 233 /* security contexts for files in filesystems that cannot support
234 a persistent label mapping or use another 234 a persistent label mapping or use another
235 fixed labeling behavior. */ 235 fixed labeling behavior. */
236 struct genfs *genfs; 236 struct genfs *genfs;
237 237
238 /* range transitions */ 238 /* range transitions */
239 struct range_trans *range_tr; 239 struct range_trans *range_tr;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2daaddbb301d..25cac5a2aa8e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -708,7 +708,7 @@ out:
708 708
709} 709}
710 710
711static int security_context_to_sid_core(char *scontext, u32 scontext_len, 711static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
712 u32 *sid, u32 def_sid, gfp_t gfp_flags) 712 u32 *sid, u32 def_sid, gfp_t gfp_flags)
713{ 713{
714 char *scontext2; 714 char *scontext2;
@@ -835,7 +835,7 @@ out:
835 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 835 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
836 * memory is available, or 0 on success. 836 * memory is available, or 0 on success.
837 */ 837 */
838int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) 838int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid)
839{ 839{
840 return security_context_to_sid_core(scontext, scontext_len, 840 return security_context_to_sid_core(scontext, scontext_len,
841 sid, SECSID_NULL, GFP_KERNEL); 841 sid, SECSID_NULL, GFP_KERNEL);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 4215971434e6..5d2ec5650e61 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -574,8 +574,8 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
574 * 574 *
575 * Returns 0 if access is permitted, an error code otherwise 575 * Returns 0 if access is permitted, an error code otherwise
576 */ 576 */
577static int smack_inode_setxattr(struct dentry *dentry, char *name, 577static int smack_inode_setxattr(struct dentry *dentry, const char *name,
578 void *value, size_t size, int flags) 578 const void *value, size_t size, int flags)
579{ 579{
580 int rc = 0; 580 int rc = 0;
581 581
@@ -604,8 +604,8 @@ static int smack_inode_setxattr(struct dentry *dentry, char *name,
604 * Set the pointer in the inode blob to the entry found 604 * Set the pointer in the inode blob to the entry found
605 * in the master label list. 605 * in the master label list.
606 */ 606 */
607static void smack_inode_post_setxattr(struct dentry *dentry, char *name, 607static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
608 void *value, size_t size, int flags) 608 const void *value, size_t size, int flags)
609{ 609{
610 struct inode_smack *isp; 610 struct inode_smack *isp;
611 char *nsp; 611 char *nsp;
@@ -641,7 +641,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, char *name,
641 * 641 *
642 * Returns 0 if access is permitted, an error code otherwise 642 * Returns 0 if access is permitted, an error code otherwise
643 */ 643 */
644static int smack_inode_getxattr(struct dentry *dentry, char *name) 644static int smack_inode_getxattr(struct dentry *dentry, const char *name)
645{ 645{
646 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 646 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
647} 647}
@@ -655,7 +655,7 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name)
655 * 655 *
656 * Returns 0 if access is permitted, an error code otherwise 656 * Returns 0 if access is permitted, an error code otherwise
657 */ 657 */
658static int smack_inode_removexattr(struct dentry *dentry, char *name) 658static int smack_inode_removexattr(struct dentry *dentry, const char *name)
659{ 659{
660 int rc = 0; 660 int rc = 0;
661 661
@@ -1242,7 +1242,7 @@ static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap)
1242 int rc; 1242 int rc;
1243 int byte; 1243 int byte;
1244 1244
1245 if (catset == 0) 1245 if (!catset)
1246 return; 1246 return;
1247 1247
1248 sap->flags |= NETLBL_SECATTR_MLS_CAT; 1248 sap->flags |= NETLBL_SECATTR_MLS_CAT;
@@ -2495,6 +2495,7 @@ struct security_operations smack_ops = {
2495 .task_wait = smack_task_wait, 2495 .task_wait = smack_task_wait,
2496 .task_reparent_to_init = cap_task_reparent_to_init, 2496 .task_reparent_to_init = cap_task_reparent_to_init,
2497 .task_to_inode = smack_task_to_inode, 2497 .task_to_inode = smack_task_to_inode,
2498 .task_prctl = cap_task_prctl,
2498 2499
2499 .ipc_permission = smack_ipc_permission, 2500 .ipc_permission = smack_ipc_permission,
2500 2501
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 5d1bee0fa513..271a835fbbe3 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -317,7 +317,7 @@ static const struct file_operations smk_load_ops = {
317/** 317/**
318 * smk_cipso_doi - initialize the CIPSO domain 318 * smk_cipso_doi - initialize the CIPSO domain
319 */ 319 */
320void smk_cipso_doi(void) 320static void smk_cipso_doi(void)
321{ 321{
322 int rc; 322 int rc;
323 struct cipso_v4_doi *doip; 323 struct cipso_v4_doi *doip;
@@ -351,7 +351,7 @@ void smk_cipso_doi(void)
351/** 351/**
352 * smk_unlbl_ambient - initialize the unlabeled domain 352 * smk_unlbl_ambient - initialize the unlabeled domain
353 */ 353 */
354void smk_unlbl_ambient(char *oldambient) 354static void smk_unlbl_ambient(char *oldambient)
355{ 355{
356 int rc; 356 int rc;
357 struct netlbl_audit audit_info; 357 struct netlbl_audit audit_info;