aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Makefile1
-rw-r--r--security/commoncap.c6
-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/security.c19
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c43
-rw-r--r--security/selinux/include/security.h4
-rw-r--r--security/selinux/ss/services.c8
-rw-r--r--security/smack/smack_lsm.c178
-rw-r--r--security/smack/smackfs.c2
22 files changed, 1185 insertions, 248 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/commoncap.c b/security/commoncap.c
index e8c3f5e46705..5edabc7542ae 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -383,8 +383,8 @@ int cap_bprm_secureexec (struct linux_binprm *bprm)
383 current->egid != current->gid); 383 current->egid != current->gid);
384} 384}
385 385
386int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, 386int cap_inode_setxattr(struct dentry *dentry, const char *name,
387 size_t size, int flags) 387 const void *value, size_t size, int flags)
388{ 388{
389 if (!strcmp(name, XATTR_NAME_CAPS)) { 389 if (!strcmp(name, XATTR_NAME_CAPS)) {
390 if (!capable(CAP_SETFCAP)) 390 if (!capable(CAP_SETFCAP))
@@ -397,7 +397,7 @@ int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
397 return 0; 397 return 0;
398} 398}
399 399
400int cap_inode_removexattr(struct dentry *dentry, char *name) 400int cap_inode_removexattr(struct dentry *dentry, const char *name)
401{ 401{
402 if (!strcmp(name, XATTR_NAME_CAPS)) { 402 if (!strcmp(name, XATTR_NAME_CAPS)) {
403 if (!capable(CAP_SETFCAP)) 403 if (!capable(CAP_SETFCAP))
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 58d4dd1af5c7..f50c6c3c32c9 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) &&
@@ -967,7 +968,7 @@ static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
967 return -EOPNOTSUPP; 968 return -EOPNOTSUPP;
968} 969}
969 970
970static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) 971static int dummy_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
971{ 972{
972 return -EOPNOTSUPP; 973 return -EOPNOTSUPP;
973} 974}
@@ -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/security.c b/security/security.c
index d5cb5898d967..59838a99b80e 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;
@@ -886,7 +886,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
886} 886}
887EXPORT_SYMBOL(security_secid_to_secctx); 887EXPORT_SYMBOL(security_secid_to_secctx);
888 888
889int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) 889int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
890{ 890{
891 return security_ops->secctx_to_secid(secdata, seclen, secid); 891 return security_ops->secctx_to_secid(secdata, seclen, secid);
892} 892}
@@ -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/avc.c b/security/selinux/avc.c
index 95a8ef4a5073..114b4b4c97b2 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -646,7 +646,7 @@ void avc_audit(u32 ssid, u32 tsid,
646 if (*p) 646 if (*p)
647 audit_log_untrustedstring(ab, p); 647 audit_log_untrustedstring(ab, p);
648 else 648 else
649 audit_log_hex(ab, p, len); 649 audit_log_n_hex(ab, p, len);
650 break; 650 break;
651 } 651 }
652 } 652 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 04acb5af8317..1c864c0efe2b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -39,6 +39,7 @@
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/syscalls.h> 40#include <linux/syscalls.h>
41#include <linux/file.h> 41#include <linux/file.h>
42#include <linux/fdtable.h>
42#include <linux/namei.h> 43#include <linux/namei.h>
43#include <linux/mount.h> 44#include <linux/mount.h>
44#include <linux/ext2_fs.h> 45#include <linux/ext2_fs.h>
@@ -2619,7 +2620,7 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2619 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); 2620 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
2620} 2621}
2621 2622
2622static int selinux_inode_setotherxattr(struct dentry *dentry, char *name) 2623static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2623{ 2624{
2624 if (!strncmp(name, XATTR_SECURITY_PREFIX, 2625 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2625 sizeof XATTR_SECURITY_PREFIX - 1)) { 2626 sizeof XATTR_SECURITY_PREFIX - 1)) {
@@ -2638,7 +2639,8 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, char *name)
2638 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); 2639 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2639} 2640}
2640 2641
2641static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) 2642static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2643 const void *value, size_t size, int flags)
2642{ 2644{
2643 struct task_security_struct *tsec = current->security; 2645 struct task_security_struct *tsec = current->security;
2644 struct inode *inode = dentry->d_inode; 2646 struct inode *inode = dentry->d_inode;
@@ -2687,8 +2689,9 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
2687 &ad); 2689 &ad);
2688} 2690}
2689 2691
2690static void selinux_inode_post_setxattr(struct dentry *dentry, char *name, 2692static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2691 void *value, size_t size, int flags) 2693 const void *value, size_t size,
2694 int flags)
2692{ 2695{
2693 struct inode *inode = dentry->d_inode; 2696 struct inode *inode = dentry->d_inode;
2694 struct inode_security_struct *isec = inode->i_security; 2697 struct inode_security_struct *isec = inode->i_security;
@@ -2711,7 +2714,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
2711 return; 2714 return;
2712} 2715}
2713 2716
2714static int selinux_inode_getxattr(struct dentry *dentry, char *name) 2717static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2715{ 2718{
2716 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2719 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2717} 2720}
@@ -2721,7 +2724,7 @@ static int selinux_inode_listxattr(struct dentry *dentry)
2721 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); 2724 return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
2722} 2725}
2723 2726
2724static int selinux_inode_removexattr(struct dentry *dentry, char *name) 2727static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
2725{ 2728{
2726 if (strcmp(name, XATTR_NAME_SELINUX)) 2729 if (strcmp(name, XATTR_NAME_SELINUX))
2727 return selinux_inode_setotherxattr(dentry, name); 2730 return selinux_inode_setotherxattr(dentry, name);
@@ -3284,9 +3287,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
3284 if (rc) 3287 if (rc)
3285 return rc; 3288 return rc;
3286 3289
3287 if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
3288 return 0;
3289
3290 if (!sig) 3290 if (!sig)
3291 perm = PROCESS__SIGNULL; /* null signal; existence test */ 3291 perm = PROCESS__SIGNULL; /* null signal; existence test */
3292 else 3292 else
@@ -5236,7 +5236,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5236 return security_sid_to_context(secid, secdata, seclen); 5236 return security_sid_to_context(secid, secdata, seclen);
5237} 5237}
5238 5238
5239static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) 5239static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
5240{ 5240{
5241 return security_context_to_sid(secdata, seclen, secid); 5241 return security_context_to_sid(secdata, seclen, secid);
5242} 5242}
@@ -5298,6 +5298,20 @@ static int selinux_key_permission(key_ref_t key_ref,
5298 SECCLASS_KEY, perm, NULL); 5298 SECCLASS_KEY, perm, NULL);
5299} 5299}
5300 5300
5301static int selinux_key_getsecurity(struct key *key, char **_buffer)
5302{
5303 struct key_security_struct *ksec = key->security;
5304 char *context = NULL;
5305 unsigned len;
5306 int rc;
5307
5308 rc = security_sid_to_context(ksec->sid, &context, &len);
5309 if (!rc)
5310 rc = len;
5311 *_buffer = context;
5312 return rc;
5313}
5314
5301#endif 5315#endif
5302 5316
5303static struct security_operations selinux_ops = { 5317static struct security_operations selinux_ops = {
@@ -5486,6 +5500,7 @@ static struct security_operations selinux_ops = {
5486 .key_alloc = selinux_key_alloc, 5500 .key_alloc = selinux_key_alloc,
5487 .key_free = selinux_key_free, 5501 .key_free = selinux_key_free,
5488 .key_permission = selinux_key_permission, 5502 .key_permission = selinux_key_permission,
5503 .key_getsecurity = selinux_key_getsecurity,
5489#endif 5504#endif
5490 5505
5491#ifdef CONFIG_AUDIT 5506#ifdef CONFIG_AUDIT
@@ -5534,14 +5549,6 @@ static __init int selinux_init(void)
5534 else 5549 else
5535 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); 5550 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
5536 5551
5537#ifdef CONFIG_KEYS
5538 /* Add security information to initial keyrings */
5539 selinux_key_alloc(&root_user_keyring, current,
5540 KEY_ALLOC_NOT_IN_QUOTA);
5541 selinux_key_alloc(&root_session_keyring, current,
5542 KEY_ALLOC_NOT_IN_QUOTA);
5543#endif
5544
5545 return 0; 5552 return 0;
5546} 5553}
5547 5554
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 6445b6440648..ad30ac4273d6 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -93,10 +93,10 @@ 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(const char *scontext, u32 scontext_len,
100 u32 *out_sid, u32 def_sid, gfp_t gfp_flags); 100 u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
101 101
102int security_get_user_sids(u32 callsid, char *username, 102int security_get_user_sids(u32 callsid, char *username,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 2daaddbb301d..dcc2e1c4fd83 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);
@@ -858,8 +858,8 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
858 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 858 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
859 * memory is available, or 0 on success. 859 * memory is available, or 0 on success.
860 */ 860 */
861int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, 861int security_context_to_sid_default(const char *scontext, u32 scontext_len,
862 u32 def_sid, gfp_t gfp_flags) 862 u32 *sid, u32 def_sid, gfp_t gfp_flags)
863{ 863{
864 return security_context_to_sid_core(scontext, scontext_len, 864 return security_context_to_sid_core(scontext, scontext_len,
865 sid, def_sid, gfp_flags); 865 sid, def_sid, gfp_flags);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 77ec16a3b68b..b5c8f9237008 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -26,6 +26,7 @@
26#include <linux/pipe_fs_i.h> 26#include <linux/pipe_fs_i.h>
27#include <net/netlabel.h> 27#include <net/netlabel.h>
28#include <net/cipso_ipv4.h> 28#include <net/cipso_ipv4.h>
29#include <linux/audit.h>
29 30
30#include "smack.h" 31#include "smack.h"
31 32
@@ -574,8 +575,8 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
574 * 575 *
575 * Returns 0 if access is permitted, an error code otherwise 576 * Returns 0 if access is permitted, an error code otherwise
576 */ 577 */
577static int smack_inode_setxattr(struct dentry *dentry, char *name, 578static int smack_inode_setxattr(struct dentry *dentry, const char *name,
578 void *value, size_t size, int flags) 579 const void *value, size_t size, int flags)
579{ 580{
580 int rc = 0; 581 int rc = 0;
581 582
@@ -604,8 +605,8 @@ static int smack_inode_setxattr(struct dentry *dentry, char *name,
604 * Set the pointer in the inode blob to the entry found 605 * Set the pointer in the inode blob to the entry found
605 * in the master label list. 606 * in the master label list.
606 */ 607 */
607static void smack_inode_post_setxattr(struct dentry *dentry, char *name, 608static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
608 void *value, size_t size, int flags) 609 const void *value, size_t size, int flags)
609{ 610{
610 struct inode_smack *isp; 611 struct inode_smack *isp;
611 char *nsp; 612 char *nsp;
@@ -641,7 +642,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, char *name,
641 * 642 *
642 * Returns 0 if access is permitted, an error code otherwise 643 * Returns 0 if access is permitted, an error code otherwise
643 */ 644 */
644static int smack_inode_getxattr(struct dentry *dentry, char *name) 645static int smack_inode_getxattr(struct dentry *dentry, const char *name)
645{ 646{
646 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 647 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
647} 648}
@@ -655,7 +656,7 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name)
655 * 656 *
656 * Returns 0 if access is permitted, an error code otherwise 657 * Returns 0 if access is permitted, an error code otherwise
657 */ 658 */
658static int smack_inode_removexattr(struct dentry *dentry, char *name) 659static int smack_inode_removexattr(struct dentry *dentry, const char *name)
659{ 660{
660 int rc = 0; 661 int rc = 0;
661 662
@@ -752,6 +753,18 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
752 return -EINVAL; 753 return -EINVAL;
753} 754}
754 755
756/**
757 * smack_inode_getsecid - Extract inode's security id
758 * @inode: inode to extract the info from
759 * @secid: where result will be saved
760 */
761static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
762{
763 struct inode_smack *isp = inode->i_security;
764
765 *secid = smack_to_secid(isp->smk_inode);
766}
767
755/* 768/*
756 * File Hooks 769 * File Hooks
757 */ 770 */
@@ -1118,15 +1131,6 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1118 int sig, u32 secid) 1131 int sig, u32 secid)
1119{ 1132{
1120 /* 1133 /*
1121 * Special cases where signals really ought to go through
1122 * in spite of policy. Stephen Smalley suggests it may
1123 * make sense to change the caller so that it doesn't
1124 * bother with the LSM hook in these cases.
1125 */
1126 if (info != SEND_SIG_NOINFO &&
1127 (is_si_special(info) || SI_FROMKERNEL(info)))
1128 return 0;
1129 /*
1130 * Sending a signal requires that the sender 1134 * Sending a signal requires that the sender
1131 * can write the receiver. 1135 * can write the receiver.
1132 */ 1136 */
@@ -1805,6 +1809,18 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
1805 return smk_curacc(isp, may); 1809 return smk_curacc(isp, may);
1806} 1810}
1807 1811
1812/**
1813 * smack_ipc_getsecid - Extract smack security id
1814 * @ipcp: the object permissions
1815 * @secid: where result will be saved
1816 */
1817static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
1818{
1819 char *smack = ipp->security;
1820
1821 *secid = smack_to_secid(smack);
1822}
1823
1808/* module stacking operations */ 1824/* module stacking operations */
1809 1825
1810/** 1826/**
@@ -2382,6 +2398,124 @@ static int smack_key_permission(key_ref_t key_ref,
2382#endif /* CONFIG_KEYS */ 2398#endif /* CONFIG_KEYS */
2383 2399
2384/* 2400/*
2401 * Smack Audit hooks
2402 *
2403 * Audit requires a unique representation of each Smack specific
2404 * rule. This unique representation is used to distinguish the
2405 * object to be audited from remaining kernel objects and also
2406 * works as a glue between the audit hooks.
2407 *
2408 * Since repository entries are added but never deleted, we'll use
2409 * the smack_known label address related to the given audit rule as
2410 * the needed unique representation. This also better fits the smack
2411 * model where nearly everything is a label.
2412 */
2413#ifdef CONFIG_AUDIT
2414
2415/**
2416 * smack_audit_rule_init - Initialize a smack audit rule
2417 * @field: audit rule fields given from user-space (audit.h)
2418 * @op: required testing operator (=, !=, >, <, ...)
2419 * @rulestr: smack label to be audited
2420 * @vrule: pointer to save our own audit rule representation
2421 *
2422 * Prepare to audit cases where (@field @op @rulestr) is true.
2423 * The label to be audited is created if necessay.
2424 */
2425static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2426{
2427 char **rule = (char **)vrule;
2428 *rule = NULL;
2429
2430 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
2431 return -EINVAL;
2432
2433 if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
2434 return -EINVAL;
2435
2436 *rule = smk_import(rulestr, 0);
2437
2438 return 0;
2439}
2440
2441/**
2442 * smack_audit_rule_known - Distinguish Smack audit rules
2443 * @krule: rule of interest, in Audit kernel representation format
2444 *
2445 * This is used to filter Smack rules from remaining Audit ones.
2446 * If it's proved that this rule belongs to us, the
2447 * audit_rule_match hook will be called to do the final judgement.
2448 */
2449static int smack_audit_rule_known(struct audit_krule *krule)
2450{
2451 struct audit_field *f;
2452 int i;
2453
2454 for (i = 0; i < krule->field_count; i++) {
2455 f = &krule->fields[i];
2456
2457 if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
2458 return 1;
2459 }
2460
2461 return 0;
2462}
2463
2464/**
2465 * smack_audit_rule_match - Audit given object ?
2466 * @secid: security id for identifying the object to test
2467 * @field: audit rule flags given from user-space
2468 * @op: required testing operator
2469 * @vrule: smack internal rule presentation
2470 * @actx: audit context associated with the check
2471 *
2472 * The core Audit hook. It's used to take the decision of
2473 * whether to audit or not to audit a given object.
2474 */
2475static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
2476 struct audit_context *actx)
2477{
2478 char *smack;
2479 char *rule = vrule;
2480
2481 if (!rule) {
2482 audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
2483 "Smack: missing rule\n");
2484 return -ENOENT;
2485 }
2486
2487 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
2488 return 0;
2489
2490 smack = smack_from_secid(secid);
2491
2492 /*
2493 * No need to do string comparisons. If a match occurs,
2494 * both pointers will point to the same smack_known
2495 * label.
2496 */
2497 if (op == AUDIT_EQUAL)
2498 return (rule == smack);
2499 if (op == AUDIT_NOT_EQUAL)
2500 return (rule != smack);
2501
2502 return 0;
2503}
2504
2505/**
2506 * smack_audit_rule_free - free smack rule representation
2507 * @vrule: rule to be freed.
2508 *
2509 * No memory was allocated.
2510 */
2511static void smack_audit_rule_free(void *vrule)
2512{
2513 /* No-op */
2514}
2515
2516#endif /* CONFIG_AUDIT */
2517
2518/*
2385 * smack_secid_to_secctx - return the smack label for a secid 2519 * smack_secid_to_secctx - return the smack label for a secid
2386 * @secid: incoming integer 2520 * @secid: incoming integer
2387 * @secdata: destination 2521 * @secdata: destination
@@ -2406,7 +2540,7 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
2406 * 2540 *
2407 * Exists for audit and networking code. 2541 * Exists for audit and networking code.
2408 */ 2542 */
2409static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) 2543static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
2410{ 2544{
2411 *secid = smack_to_secid(secdata); 2545 *secid = smack_to_secid(secdata);
2412 return 0; 2546 return 0;
@@ -2467,6 +2601,7 @@ struct security_operations smack_ops = {
2467 .inode_getsecurity = smack_inode_getsecurity, 2601 .inode_getsecurity = smack_inode_getsecurity,
2468 .inode_setsecurity = smack_inode_setsecurity, 2602 .inode_setsecurity = smack_inode_setsecurity,
2469 .inode_listsecurity = smack_inode_listsecurity, 2603 .inode_listsecurity = smack_inode_listsecurity,
2604 .inode_getsecid = smack_inode_getsecid,
2470 2605
2471 .file_permission = smack_file_permission, 2606 .file_permission = smack_file_permission,
2472 .file_alloc_security = smack_file_alloc_security, 2607 .file_alloc_security = smack_file_alloc_security,
@@ -2498,6 +2633,7 @@ struct security_operations smack_ops = {
2498 .task_prctl = cap_task_prctl, 2633 .task_prctl = cap_task_prctl,
2499 2634
2500 .ipc_permission = smack_ipc_permission, 2635 .ipc_permission = smack_ipc_permission,
2636 .ipc_getsecid = smack_ipc_getsecid,
2501 2637
2502 .msg_msg_alloc_security = smack_msg_msg_alloc_security, 2638 .msg_msg_alloc_security = smack_msg_msg_alloc_security,
2503 .msg_msg_free_security = smack_msg_msg_free_security, 2639 .msg_msg_free_security = smack_msg_msg_free_security,
@@ -2542,12 +2678,22 @@ struct security_operations smack_ops = {
2542 .sk_free_security = smack_sk_free_security, 2678 .sk_free_security = smack_sk_free_security,
2543 .sock_graft = smack_sock_graft, 2679 .sock_graft = smack_sock_graft,
2544 .inet_conn_request = smack_inet_conn_request, 2680 .inet_conn_request = smack_inet_conn_request,
2681
2545 /* key management security hooks */ 2682 /* key management security hooks */
2546#ifdef CONFIG_KEYS 2683#ifdef CONFIG_KEYS
2547 .key_alloc = smack_key_alloc, 2684 .key_alloc = smack_key_alloc,
2548 .key_free = smack_key_free, 2685 .key_free = smack_key_free,
2549 .key_permission = smack_key_permission, 2686 .key_permission = smack_key_permission,
2550#endif /* CONFIG_KEYS */ 2687#endif /* CONFIG_KEYS */
2688
2689 /* Audit hooks */
2690#ifdef CONFIG_AUDIT
2691 .audit_rule_init = smack_audit_rule_init,
2692 .audit_rule_known = smack_audit_rule_known,
2693 .audit_rule_match = smack_audit_rule_match,
2694 .audit_rule_free = smack_audit_rule_free,
2695#endif /* CONFIG_AUDIT */
2696
2551 .secid_to_secctx = smack_secid_to_secctx, 2697 .secid_to_secctx = smack_secid_to_secctx,
2552 .secctx_to_secid = smack_secctx_to_secid, 2698 .secctx_to_secid = smack_secctx_to_secid,
2553 .release_secctx = smack_release_secctx, 2699 .release_secctx = smack_release_secctx,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index a5da5a8cfe9b..271a835fbbe3 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -324,6 +324,7 @@ static void smk_cipso_doi(void)
324 struct netlbl_audit audit_info; 324 struct netlbl_audit audit_info;
325 325
326 audit_info.loginuid = audit_get_loginuid(current); 326 audit_info.loginuid = audit_get_loginuid(current);
327 audit_info.sessionid = audit_get_sessionid(current);
327 audit_info.secid = smack_to_secid(current->security); 328 audit_info.secid = smack_to_secid(current->security);
328 329
329 rc = netlbl_cfg_map_del(NULL, &audit_info); 330 rc = netlbl_cfg_map_del(NULL, &audit_info);
@@ -356,6 +357,7 @@ static void smk_unlbl_ambient(char *oldambient)
356 struct netlbl_audit audit_info; 357 struct netlbl_audit audit_info;
357 358
358 audit_info.loginuid = audit_get_loginuid(current); 359 audit_info.loginuid = audit_get_loginuid(current);
360 audit_info.sessionid = audit_get_sessionid(current);
359 audit_info.secid = smack_to_secid(current->security); 361 audit_info.secid = smack_to_secid(current->security);
360 362
361 if (oldambient != NULL) { 363 if (oldambient != NULL) {