aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c13
-rw-r--r--security/keys/process_keys.c7
-rw-r--r--security/seclvl.c210
-rw-r--r--security/selinux/hooks.c60
-rw-r--r--security/selinux/include/xfrm.h12
-rw-r--r--security/selinux/nlmsgtab.c7
-rw-r--r--security/selinux/selinuxfs.c112
-rw-r--r--security/selinux/ss/services.c9
-rw-r--r--security/selinux/xfrm.c68
9 files changed, 317 insertions, 181 deletions
diff --git a/security/dummy.c b/security/dummy.c
index f1a5bd98bf10..a678f094b72d 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -763,8 +763,14 @@ static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb)
763 return 0; 763 return 0;
764} 764}
765 765
766static int dummy_socket_getpeersec(struct socket *sock, char __user *optval, 766static int dummy_socket_getpeersec_stream(struct socket *sock, char __user *optval,
767 int __user *optlen, unsigned len) 767 int __user *optlen, unsigned len)
768{
769 return -ENOPROTOOPT;
770}
771
772static int dummy_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
773 u32 *seclen)
768{ 774{
769 return -ENOPROTOOPT; 775 return -ENOPROTOOPT;
770} 776}
@@ -1002,7 +1008,8 @@ void security_fixup_ops (struct security_operations *ops)
1002 set_to_dummy_if_null(ops, socket_getsockopt); 1008 set_to_dummy_if_null(ops, socket_getsockopt);
1003 set_to_dummy_if_null(ops, socket_shutdown); 1009 set_to_dummy_if_null(ops, socket_shutdown);
1004 set_to_dummy_if_null(ops, socket_sock_rcv_skb); 1010 set_to_dummy_if_null(ops, socket_sock_rcv_skb);
1005 set_to_dummy_if_null(ops, socket_getpeersec); 1011 set_to_dummy_if_null(ops, socket_getpeersec_stream);
1012 set_to_dummy_if_null(ops, socket_getpeersec_dgram);
1006 set_to_dummy_if_null(ops, sk_alloc_security); 1013 set_to_dummy_if_null(ops, sk_alloc_security);
1007 set_to_dummy_if_null(ops, sk_free_security); 1014 set_to_dummy_if_null(ops, sk_free_security);
1008 set_to_dummy_if_null(ops, sk_getsid); 1015 set_to_dummy_if_null(ops, sk_getsid);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 74cb79eb917e..f6940618e345 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -16,11 +16,12 @@
16#include <linux/keyctl.h> 16#include <linux/keyctl.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/mutex.h>
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include "internal.h" 21#include "internal.h"
21 22
22/* session keyring create vs join semaphore */ 23/* session keyring create vs join semaphore */
23static DECLARE_MUTEX(key_session_sem); 24static DEFINE_MUTEX(key_session_mutex);
24 25
25/* the root user's tracking struct */ 26/* the root user's tracking struct */
26struct key_user root_key_user = { 27struct key_user root_key_user = {
@@ -711,7 +712,7 @@ long join_session_keyring(const char *name)
711 } 712 }
712 713
713 /* allow the user to join or create a named keyring */ 714 /* allow the user to join or create a named keyring */
714 down(&key_session_sem); 715 mutex_lock(&key_session_mutex);
715 716
716 /* look for an existing keyring of this name */ 717 /* look for an existing keyring of this name */
717 keyring = find_keyring_by_name(name, 0); 718 keyring = find_keyring_by_name(name, 0);
@@ -737,7 +738,7 @@ long join_session_keyring(const char *name)
737 key_put(keyring); 738 key_put(keyring);
738 739
739error2: 740error2:
740 up(&key_session_sem); 741 mutex_unlock(&key_session_mutex);
741error: 742error:
742 return ret; 743 return ret;
743 744
diff --git a/security/seclvl.c b/security/seclvl.c
index 8529ea6f7aa8..441beaf1bbc1 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -8,6 +8,7 @@
8 * Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com> 8 * Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com>
9 * Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com> 9 * Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com>
10 * Copyright (c) 2002 International Business Machines <robb@austin.ibm.com> 10 * Copyright (c) 2002 International Business Machines <robb@austin.ibm.com>
11 * Copyright (c) 2006 Davi E. M. Arnaut <davi.arnaut@gmail.com>
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -31,6 +32,7 @@
31#include <linux/kobject.h> 32#include <linux/kobject.h>
32#include <linux/crypto.h> 33#include <linux/crypto.h>
33#include <asm/scatterlist.h> 34#include <asm/scatterlist.h>
35#include <linux/scatterlist.h>
34#include <linux/gfp.h> 36#include <linux/gfp.h>
35#include <linux/sysfs.h> 37#include <linux/sysfs.h>
36 38
@@ -194,35 +196,27 @@ static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
194 * people... 196 * people...
195 */ 197 */
196static int 198static int
197plaintext_to_sha1(unsigned char *hash, const char *plaintext, int len) 199plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
198{ 200{
199 char *pgVirtAddr;
200 struct crypto_tfm *tfm; 201 struct crypto_tfm *tfm;
201 struct scatterlist sg[1]; 202 struct scatterlist sg;
202 if (len > PAGE_SIZE) { 203 if (len > PAGE_SIZE) {
203 seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d " 204 seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
204 "characters). Largest possible is %lu " 205 "characters). Largest possible is %lu "
205 "bytes.\n", len, PAGE_SIZE); 206 "bytes.\n", len, PAGE_SIZE);
206 return -ENOMEM; 207 return -EINVAL;
207 } 208 }
208 tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP); 209 tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP);
209 if (tfm == NULL) { 210 if (tfm == NULL) {
210 seclvl_printk(0, KERN_ERR, 211 seclvl_printk(0, KERN_ERR,
211 "Failed to load transform for SHA1\n"); 212 "Failed to load transform for SHA1\n");
212 return -ENOSYS; 213 return -EINVAL;
213 } 214 }
214 // Just get a new page; don't play around with page boundaries 215 sg_init_one(&sg, (u8 *)plaintext, len);
215 // and scatterlists.
216 pgVirtAddr = (char *)__get_free_page(GFP_KERNEL);
217 sg[0].page = virt_to_page(pgVirtAddr);
218 sg[0].offset = 0;
219 sg[0].length = len;
220 strncpy(pgVirtAddr, plaintext, len);
221 crypto_digest_init(tfm); 216 crypto_digest_init(tfm);
222 crypto_digest_update(tfm, sg, 1); 217 crypto_digest_update(tfm, &sg, 1);
223 crypto_digest_final(tfm, hash); 218 crypto_digest_final(tfm, hash);
224 crypto_free_tfm(tfm); 219 crypto_free_tfm(tfm);
225 free_page((unsigned long)pgVirtAddr);
226 return 0; 220 return 0;
227} 221}
228 222
@@ -234,11 +228,9 @@ static ssize_t
234passwd_write_file(struct file * file, const char __user * buf, 228passwd_write_file(struct file * file, const char __user * buf,
235 size_t count, loff_t *ppos) 229 size_t count, loff_t *ppos)
236{ 230{
237 int i; 231 char *p;
238 unsigned char tmp[SHA1_DIGEST_SIZE];
239 char *page;
240 int rc;
241 int len; 232 int len;
233 unsigned char tmp[SHA1_DIGEST_SIZE];
242 234
243 if (!*passwd && !*sha1_passwd) { 235 if (!*passwd && !*sha1_passwd) {
244 seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the " 236 seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
@@ -251,38 +243,39 @@ passwd_write_file(struct file * file, const char __user * buf,
251 return -EINVAL; 243 return -EINVAL;
252 } 244 }
253 245
254 if (count < 0 || count >= PAGE_SIZE) 246 if (count >= PAGE_SIZE)
255 return -EINVAL; 247 return -EINVAL;
256 if (*ppos != 0) 248 if (*ppos != 0)
257 return -EINVAL; 249 return -EINVAL;
258 page = (char *)get_zeroed_page(GFP_KERNEL); 250 p = kmalloc(count, GFP_KERNEL);
259 if (!page) 251 if (!p)
260 return -ENOMEM; 252 return -ENOMEM;
261 len = -EFAULT; 253 len = -EFAULT;
262 if (copy_from_user(page, buf, count)) 254 if (copy_from_user(p, buf, count))
263 goto out; 255 goto out;
264 256
265 len = strlen(page); 257 len = count;
266 /* ``echo "secret" > seclvl/passwd'' includes a newline */ 258 /* ``echo "secret" > seclvl/passwd'' includes a newline */
267 if (page[len - 1] == '\n') 259 if (p[len - 1] == '\n')
268 len--; 260 len--;
269 /* Hash the password, then compare the hashed values */ 261 /* Hash the password, then compare the hashed values */
270 if ((rc = plaintext_to_sha1(tmp, page, len))) { 262 if ((len = plaintext_to_sha1(tmp, p, len))) {
271 seclvl_printk(0, KERN_ERR, "Error hashing password: rc = " 263 seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
272 "[%d]\n", rc); 264 "[%d]\n", len);
273 return rc; 265 goto out;
274 }
275 for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
276 if (hashedPassword[i] != tmp[i])
277 return -EPERM;
278 } 266 }
267
268 len = -EPERM;
269 if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE))
270 goto out;
271
279 seclvl_printk(0, KERN_INFO, 272 seclvl_printk(0, KERN_INFO,
280 "Password accepted; seclvl reduced to 0.\n"); 273 "Password accepted; seclvl reduced to 0.\n");
281 seclvl = 0; 274 seclvl = 0;
282 len = count; 275 len = count;
283 276
284out: 277out:
285 free_page((unsigned long)page); 278 kfree (p);
286 return len; 279 return len;
287} 280}
288 281
@@ -295,13 +288,11 @@ static struct file_operations passwd_file_ops = {
295 */ 288 */
296static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child) 289static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
297{ 290{
298 if (seclvl >= 0) { 291 if (seclvl >= 0 && child->pid == 1) {
299 if (child->pid == 1) { 292 seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
300 seclvl_printk(1, KERN_WARNING, "Attempt to ptrace " 293 "the init process dissallowed in "
301 "the init process dissallowed in " 294 "secure level %d\n", seclvl);
302 "secure level %d\n", seclvl); 295 return -EPERM;
303 return -EPERM;
304 }
305 } 296 }
306 return 0; 297 return 0;
307} 298}
@@ -312,55 +303,54 @@ static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
312 */ 303 */
313static int seclvl_capable(struct task_struct *tsk, int cap) 304static int seclvl_capable(struct task_struct *tsk, int cap)
314{ 305{
306 int rc = 0;
307
315 /* init can do anything it wants */ 308 /* init can do anything it wants */
316 if (tsk->pid == 1) 309 if (tsk->pid == 1)
317 return 0; 310 return 0;
318 311
319 switch (seclvl) { 312 if (seclvl > 0) {
320 case 2: 313 rc = -EPERM;
321 /* fall through */ 314
322 case 1: 315 if (cap == CAP_LINUX_IMMUTABLE)
323 if (cap == CAP_LINUX_IMMUTABLE) {
324 seclvl_printk(1, KERN_WARNING, "Attempt to modify " 316 seclvl_printk(1, KERN_WARNING, "Attempt to modify "
325 "the IMMUTABLE and/or APPEND extended " 317 "the IMMUTABLE and/or APPEND extended "
326 "attribute on a file with the IMMUTABLE " 318 "attribute on a file with the IMMUTABLE "
327 "and/or APPEND extended attribute set " 319 "and/or APPEND extended attribute set "
328 "denied in seclvl [%d]\n", seclvl); 320 "denied in seclvl [%d]\n", seclvl);
329 return -EPERM; 321 else if (cap == CAP_SYS_RAWIO)
330 } else if (cap == CAP_SYS_RAWIO) { // Somewhat broad...
331 seclvl_printk(1, KERN_WARNING, "Attempt to perform " 322 seclvl_printk(1, KERN_WARNING, "Attempt to perform "
332 "raw I/O while in secure level [%d] " 323 "raw I/O while in secure level [%d] "
333 "denied\n", seclvl); 324 "denied\n", seclvl);
334 return -EPERM; 325 else if (cap == CAP_NET_ADMIN)
335 } else if (cap == CAP_NET_ADMIN) {
336 seclvl_printk(1, KERN_WARNING, "Attempt to perform " 326 seclvl_printk(1, KERN_WARNING, "Attempt to perform "
337 "network administrative task while " 327 "network administrative task while "
338 "in secure level [%d] denied\n", seclvl); 328 "in secure level [%d] denied\n", seclvl);
339 return -EPERM; 329 else if (cap == CAP_SETUID)
340 } else if (cap == CAP_SETUID) {
341 seclvl_printk(1, KERN_WARNING, "Attempt to setuid " 330 seclvl_printk(1, KERN_WARNING, "Attempt to setuid "
342 "while in secure level [%d] denied\n", 331 "while in secure level [%d] denied\n",
343 seclvl); 332 seclvl);
344 return -EPERM; 333 else if (cap == CAP_SETGID)
345 } else if (cap == CAP_SETGID) {
346 seclvl_printk(1, KERN_WARNING, "Attempt to setgid " 334 seclvl_printk(1, KERN_WARNING, "Attempt to setgid "
347 "while in secure level [%d] denied\n", 335 "while in secure level [%d] denied\n",
348 seclvl); 336 seclvl);
349 } else if (cap == CAP_SYS_MODULE) { 337 else if (cap == CAP_SYS_MODULE)
350 seclvl_printk(1, KERN_WARNING, "Attempt to perform " 338 seclvl_printk(1, KERN_WARNING, "Attempt to perform "
351 "a module operation while in secure " 339 "a module operation while in secure "
352 "level [%d] denied\n", seclvl); 340 "level [%d] denied\n", seclvl);
353 return -EPERM; 341 else
354 } 342 rc = 0;
355 break;
356 default:
357 break;
358 } 343 }
359 /* from dummy.c */ 344
360 if (cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0) 345 if (!rc) {
361 return 0; /* capability granted */ 346 if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0))
362 seclvl_printk(1, KERN_WARNING, "Capability denied\n"); 347 rc = -EPERM;
363 return -EPERM; /* capability denied */ 348 }
349
350 if (rc)
351 seclvl_printk(1, KERN_WARNING, "Capability denied\n");
352
353 return rc;
364} 354}
365 355
366/** 356/**
@@ -466,12 +456,9 @@ static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
466static void seclvl_file_free_security(struct file *filp) 456static void seclvl_file_free_security(struct file *filp)
467{ 457{
468 struct dentry *dentry = filp->f_dentry; 458 struct dentry *dentry = filp->f_dentry;
469 struct inode *inode = NULL;
470 459
471 if (dentry) { 460 if (dentry)
472 inode = dentry->d_inode; 461 seclvl_bd_release(dentry->d_inode);
473 seclvl_bd_release(inode);
474 }
475} 462}
476 463
477/** 464/**
@@ -479,9 +466,7 @@ static void seclvl_file_free_security(struct file *filp)
479 */ 466 */
480static int seclvl_umount(struct vfsmount *mnt, int flags) 467static int seclvl_umount(struct vfsmount *mnt, int flags)
481{ 468{
482 if (current->pid == 1) 469 if (current->pid != 1 && seclvl == 2) {
483 return 0;
484 if (seclvl == 2) {
485 seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure " 470 seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
486 "level %d\n", seclvl); 471 "level %d\n", seclvl);
487 return -EPERM; 472 return -EPERM;
@@ -505,8 +490,9 @@ static struct security_operations seclvl_ops = {
505static int processPassword(void) 490static int processPassword(void)
506{ 491{
507 int rc = 0; 492 int rc = 0;
508 hashedPassword[0] = '\0';
509 if (*passwd) { 493 if (*passwd) {
494 char *p;
495
510 if (*sha1_passwd) { 496 if (*sha1_passwd) {
511 seclvl_printk(0, KERN_ERR, "Error: Both " 497 seclvl_printk(0, KERN_ERR, "Error: Both "
512 "passwd and sha1_passwd " 498 "passwd and sha1_passwd "
@@ -514,12 +500,16 @@ static int processPassword(void)
514 "exclusive.\n"); 500 "exclusive.\n");
515 return -EINVAL; 501 return -EINVAL;
516 } 502 }
517 if ((rc = plaintext_to_sha1(hashedPassword, passwd, 503
518 strlen(passwd)))) { 504 p = kstrdup(passwd, GFP_KERNEL);
505 if (p == NULL)
506 return -ENOMEM;
507
508 if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p))))
519 seclvl_printk(0, KERN_ERR, "Error: SHA1 support not " 509 seclvl_printk(0, KERN_ERR, "Error: SHA1 support not "
520 "in kernel\n"); 510 "in kernel\n");
521 return rc; 511
522 } 512 kfree (p);
523 /* All static data goes to the BSS, which zero's the 513 /* All static data goes to the BSS, which zero's the
524 * plaintext password out for us. */ 514 * plaintext password out for us. */
525 } else if (*sha1_passwd) { // Base 16 515 } else if (*sha1_passwd) { // Base 16
@@ -542,7 +532,7 @@ static int processPassword(void)
542 sha1_passwd[i + 2] = tmp; 532 sha1_passwd[i + 2] = tmp;
543 } 533 }
544 } 534 }
545 return 0; 535 return rc;
546} 536}
547 537
548/** 538/**
@@ -552,28 +542,46 @@ struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
552 542
553static int seclvlfs_register(void) 543static int seclvlfs_register(void)
554{ 544{
545 int rc = 0;
546
555 dir_ino = securityfs_create_dir("seclvl", NULL); 547 dir_ino = securityfs_create_dir("seclvl", NULL);
556 if (!dir_ino) 548
557 return -EFAULT; 549 if (IS_ERR(dir_ino))
550 return PTR_ERR(dir_ino);
558 551
559 seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR, 552 seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
560 dir_ino, &seclvl, &seclvl_file_ops); 553 dir_ino, &seclvl, &seclvl_file_ops);
561 if (!seclvl_ino) 554 if (IS_ERR(seclvl_ino)) {
555 rc = PTR_ERR(seclvl_ino);
562 goto out_deldir; 556 goto out_deldir;
557 }
563 if (*passwd || *sha1_passwd) { 558 if (*passwd || *sha1_passwd) {
564 passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR, 559 passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
565 dir_ino, NULL, &passwd_file_ops); 560 dir_ino, NULL, &passwd_file_ops);
566 if (!passwd_ino) 561 if (IS_ERR(passwd_ino)) {
562 rc = PTR_ERR(passwd_ino);
567 goto out_delf; 563 goto out_delf;
564 }
568 } 565 }
569 return 0; 566 return rc;
567
568out_delf:
569 securityfs_remove(seclvl_ino);
570 570
571out_deldir: 571out_deldir:
572 securityfs_remove(dir_ino); 572 securityfs_remove(dir_ino);
573out_delf: 573
574 return rc;
575}
576
577static void seclvlfs_unregister(void)
578{
574 securityfs_remove(seclvl_ino); 579 securityfs_remove(seclvl_ino);
575 580
576 return -EFAULT; 581 if (*passwd || *sha1_passwd)
582 securityfs_remove(passwd_ino);
583
584 securityfs_remove(dir_ino);
577} 585}
578 586
579/** 587/**
@@ -582,6 +590,8 @@ out_delf:
582static int __init seclvl_init(void) 590static int __init seclvl_init(void)
583{ 591{
584 int rc = 0; 592 int rc = 0;
593 static char once;
594
585 if (verbosity < 0 || verbosity > 1) { 595 if (verbosity < 0 || verbosity > 1) {
586 printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 " 596 printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 "
587 "are valid values\n", verbosity); 597 "are valid values\n", verbosity);
@@ -600,6 +610,11 @@ static int __init seclvl_init(void)
600 "module parameter(s): rc = [%d]\n", rc); 610 "module parameter(s): rc = [%d]\n", rc);
601 goto exit; 611 goto exit;
602 } 612 }
613
614 if ((rc = seclvlfs_register())) {
615 seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
616 goto exit;
617 }
603 /* register ourselves with the security framework */ 618 /* register ourselves with the security framework */
604 if (register_security(&seclvl_ops)) { 619 if (register_security(&seclvl_ops)) {
605 seclvl_printk(0, KERN_ERR, 620 seclvl_printk(0, KERN_ERR,
@@ -611,20 +626,24 @@ static int __init seclvl_init(void)
611 seclvl_printk(0, KERN_ERR, "seclvl: Failure " 626 seclvl_printk(0, KERN_ERR, "seclvl: Failure "
612 "registering with primary security " 627 "registering with primary security "
613 "module.\n"); 628 "module.\n");
629 seclvlfs_unregister();
614 goto exit; 630 goto exit;
615 } /* if primary module registered */ 631 } /* if primary module registered */
616 secondary = 1; 632 secondary = 1;
617 } /* if we registered ourselves with the security framework */ 633 } /* if we registered ourselves with the security framework */
618 if ((rc = seclvlfs_register())) { 634
619 seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
620 goto exit;
621 }
622 seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n"); 635 seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n");
636
637 if (once) {
638 once = 1;
639 seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been "
640 "buggy for ages. Also, be warned that "
641 "Securelevels are useless.");
642 }
623 exit: 643 exit:
624 if (rc) { 644 if (rc)
625 printk(KERN_ERR "seclvl: Error during initialization: rc = " 645 printk(KERN_ERR "seclvl: Error during initialization: rc = "
626 "[%d]\n", rc); 646 "[%d]\n", rc);
627 }
628 return rc; 647 return rc;
629} 648}
630 649
@@ -633,17 +652,14 @@ static int __init seclvl_init(void)
633 */ 652 */
634static void __exit seclvl_exit(void) 653static void __exit seclvl_exit(void)
635{ 654{
636 securityfs_remove(seclvl_ino); 655 seclvlfs_unregister();
637 if (*passwd || *sha1_passwd) 656
638 securityfs_remove(passwd_ino); 657 if (secondary)
639 securityfs_remove(dir_ino);
640 if (secondary == 1) {
641 mod_unreg_security(MY_NAME, &seclvl_ops); 658 mod_unreg_security(MY_NAME, &seclvl_ops);
642 } else if (unregister_security(&seclvl_ops)) { 659 else if (unregister_security(&seclvl_ops))
643 seclvl_printk(0, KERN_INFO, 660 seclvl_printk(0, KERN_INFO,
644 "seclvl: Failure unregistering with the " 661 "seclvl: Failure unregistering with the "
645 "kernel\n"); 662 "kernel\n");
646 }
647} 663}
648 664
649module_init(seclvl_init); 665module_init(seclvl_init);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b65c201e9ff5..ccaf988f3729 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -117,6 +117,8 @@ static struct security_operations *secondary_ops = NULL;
117static LIST_HEAD(superblock_security_head); 117static LIST_HEAD(superblock_security_head);
118static DEFINE_SPINLOCK(sb_security_lock); 118static DEFINE_SPINLOCK(sb_security_lock);
119 119
120static kmem_cache_t *sel_inode_cache;
121
120/* Allocate and free functions for each kind of security blob. */ 122/* Allocate and free functions for each kind of security blob. */
121 123
122static int task_alloc_security(struct task_struct *task) 124static int task_alloc_security(struct task_struct *task)
@@ -146,10 +148,11 @@ static int inode_alloc_security(struct inode *inode)
146 struct task_security_struct *tsec = current->security; 148 struct task_security_struct *tsec = current->security;
147 struct inode_security_struct *isec; 149 struct inode_security_struct *isec;
148 150
149 isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL); 151 isec = kmem_cache_alloc(sel_inode_cache, SLAB_KERNEL);
150 if (!isec) 152 if (!isec)
151 return -ENOMEM; 153 return -ENOMEM;
152 154
155 memset(isec, 0, sizeof(*isec));
153 init_MUTEX(&isec->sem); 156 init_MUTEX(&isec->sem);
154 INIT_LIST_HEAD(&isec->list); 157 INIT_LIST_HEAD(&isec->list);
155 isec->inode = inode; 158 isec->inode = inode;
@@ -172,7 +175,7 @@ static void inode_free_security(struct inode *inode)
172 spin_unlock(&sbsec->isec_lock); 175 spin_unlock(&sbsec->isec_lock);
173 176
174 inode->i_security = NULL; 177 inode->i_security = NULL;
175 kfree(isec); 178 kmem_cache_free(sel_inode_cache, isec);
176} 179}
177 180
178static int file_alloc_security(struct file *file) 181static int file_alloc_security(struct file *file)
@@ -1929,7 +1932,6 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1929 struct task_security_struct *tsec; 1932 struct task_security_struct *tsec;
1930 struct inode_security_struct *dsec; 1933 struct inode_security_struct *dsec;
1931 struct superblock_security_struct *sbsec; 1934 struct superblock_security_struct *sbsec;
1932 struct inode_security_struct *isec;
1933 u32 newsid, clen; 1935 u32 newsid, clen;
1934 int rc; 1936 int rc;
1935 char *namep = NULL, *context; 1937 char *namep = NULL, *context;
@@ -1937,7 +1939,6 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1937 tsec = current->security; 1939 tsec = current->security;
1938 dsec = dir->i_security; 1940 dsec = dir->i_security;
1939 sbsec = dir->i_sb->s_security; 1941 sbsec = dir->i_sb->s_security;
1940 isec = inode->i_security;
1941 1942
1942 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) { 1943 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
1943 newsid = tsec->create_sid; 1944 newsid = tsec->create_sid;
@@ -1957,7 +1958,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
1957 1958
1958 inode_security_set_sid(inode, newsid); 1959 inode_security_set_sid(inode, newsid);
1959 1960
1960 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 1961 if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
1961 return -EOPNOTSUPP; 1962 return -EOPNOTSUPP;
1962 1963
1963 if (name) { 1964 if (name) {
@@ -3318,24 +3319,38 @@ out:
3318 return err; 3319 return err;
3319} 3320}
3320 3321
3321static int selinux_socket_getpeersec(struct socket *sock, char __user *optval, 3322static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
3322 int __user *optlen, unsigned len) 3323 int __user *optlen, unsigned len)
3323{ 3324{
3324 int err = 0; 3325 int err = 0;
3325 char *scontext; 3326 char *scontext;
3326 u32 scontext_len; 3327 u32 scontext_len;
3327 struct sk_security_struct *ssec; 3328 struct sk_security_struct *ssec;
3328 struct inode_security_struct *isec; 3329 struct inode_security_struct *isec;
3330 u32 peer_sid = 0;
3329 3331
3330 isec = SOCK_INODE(sock)->i_security; 3332 isec = SOCK_INODE(sock)->i_security;
3331 if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) { 3333
3334 /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
3335 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
3336 ssec = sock->sk->sk_security;
3337 peer_sid = ssec->peer_sid;
3338 }
3339 else if (isec->sclass == SECCLASS_TCP_SOCKET) {
3340 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3341
3342 if (peer_sid == SECSID_NULL) {
3343 err = -ENOPROTOOPT;
3344 goto out;
3345 }
3346 }
3347 else {
3332 err = -ENOPROTOOPT; 3348 err = -ENOPROTOOPT;
3333 goto out; 3349 goto out;
3334 } 3350 }
3335 3351
3336 ssec = sock->sk->sk_security; 3352 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
3337 3353
3338 err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len);
3339 if (err) 3354 if (err)
3340 goto out; 3355 goto out;
3341 3356
@@ -3356,6 +3371,23 @@ out:
3356 return err; 3371 return err;
3357} 3372}
3358 3373
3374static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3375{
3376 int err = 0;
3377 u32 peer_sid = selinux_socket_getpeer_dgram(skb);
3378
3379 if (peer_sid == SECSID_NULL)
3380 return -EINVAL;
3381
3382 err = security_sid_to_context(peer_sid, secdata, seclen);
3383 if (err)
3384 return err;
3385
3386 return 0;
3387}
3388
3389
3390
3359static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 3391static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
3360{ 3392{
3361 return sk_alloc_security(sk, family, priority); 3393 return sk_alloc_security(sk, family, priority);
@@ -4344,7 +4376,8 @@ static struct security_operations selinux_ops = {
4344 .socket_setsockopt = selinux_socket_setsockopt, 4376 .socket_setsockopt = selinux_socket_setsockopt,
4345 .socket_shutdown = selinux_socket_shutdown, 4377 .socket_shutdown = selinux_socket_shutdown,
4346 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb, 4378 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb,
4347 .socket_getpeersec = selinux_socket_getpeersec, 4379 .socket_getpeersec_stream = selinux_socket_getpeersec_stream,
4380 .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
4348 .sk_alloc_security = selinux_sk_alloc_security, 4381 .sk_alloc_security = selinux_sk_alloc_security,
4349 .sk_free_security = selinux_sk_free_security, 4382 .sk_free_security = selinux_sk_free_security,
4350 .sk_getsid = selinux_sk_getsid_security, 4383 .sk_getsid = selinux_sk_getsid_security,
@@ -4376,6 +4409,9 @@ static __init int selinux_init(void)
4376 tsec = current->security; 4409 tsec = current->security;
4377 tsec->osid = tsec->sid = SECINITSID_KERNEL; 4410 tsec->osid = tsec->sid = SECINITSID_KERNEL;
4378 4411
4412 sel_inode_cache = kmem_cache_create("selinux_inode_security",
4413 sizeof(struct inode_security_struct),
4414 0, SLAB_PANIC, NULL, NULL);
4379 avc_init(); 4415 avc_init();
4380 4416
4381 original_ops = secondary_ops = security_ops; 4417 original_ops = secondary_ops = security_ops;
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 8e87996c6dd5..c10f1fc41502 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -39,6 +39,8 @@ static inline u32 selinux_no_sk_sid(struct flowi *fl)
39#ifdef CONFIG_SECURITY_NETWORK_XFRM 39#ifdef CONFIG_SECURITY_NETWORK_XFRM
40int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb); 40int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
41int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb); 41int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
42u32 selinux_socket_getpeer_stream(struct sock *sk);
43u32 selinux_socket_getpeer_dgram(struct sk_buff *skb);
42#else 44#else
43static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) 45static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
44{ 46{
@@ -49,6 +51,16 @@ static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
49{ 51{
50 return NF_ACCEPT; 52 return NF_ACCEPT;
51} 53}
54
55static inline int selinux_socket_getpeer_stream(struct sock *sk)
56{
57 return SECSID_NULL;
58}
59
60static inline int selinux_socket_getpeer_dgram(struct sk_buff *skb)
61{
62 return SECSID_NULL;
63}
52#endif 64#endif
53 65
54#endif /* _SELINUX_XFRM_H_ */ 66#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 69b9329b2054..85e399259832 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -88,8 +88,15 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] =
88 { XFRM_MSG_DELPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 88 { XFRM_MSG_DELPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
89 { XFRM_MSG_GETPOLICY, NETLINK_XFRM_SOCKET__NLMSG_READ }, 89 { XFRM_MSG_GETPOLICY, NETLINK_XFRM_SOCKET__NLMSG_READ },
90 { XFRM_MSG_ALLOCSPI, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 90 { XFRM_MSG_ALLOCSPI, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
91 { XFRM_MSG_ACQUIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
92 { XFRM_MSG_EXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
91 { XFRM_MSG_UPDPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 93 { XFRM_MSG_UPDPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
92 { XFRM_MSG_UPDSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 94 { XFRM_MSG_UPDSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
95 { XFRM_MSG_POLEXPIRE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
96 { XFRM_MSG_FLUSHSA, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
97 { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
98 { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
99 { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ },
93}; 100};
94 101
95static struct nlmsg_perm nlmsg_audit_perms[] = 102static struct nlmsg_perm nlmsg_audit_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index b5fa02d17b1e..f5d78365488f 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/vmalloc.h> 16#include <linux/vmalloc.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/mutex.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/string.h> 20#include <linux/string.h>
20#include <linux/security.h> 21#include <linux/security.h>
@@ -44,7 +45,7 @@ static int __init checkreqprot_setup(char *str)
44__setup("checkreqprot=", checkreqprot_setup); 45__setup("checkreqprot=", checkreqprot_setup);
45 46
46 47
47static DECLARE_MUTEX(sel_sem); 48static DEFINE_MUTEX(sel_mutex);
48 49
49/* global data for booleans */ 50/* global data for booleans */
50static struct dentry *bool_dir = NULL; 51static struct dentry *bool_dir = NULL;
@@ -230,7 +231,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
230 ssize_t length; 231 ssize_t length;
231 void *data = NULL; 232 void *data = NULL;
232 233
233 down(&sel_sem); 234 mutex_lock(&sel_mutex);
234 235
235 length = task_has_security(current, SECURITY__LOAD_POLICY); 236 length = task_has_security(current, SECURITY__LOAD_POLICY);
236 if (length) 237 if (length)
@@ -262,7 +263,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
262 else 263 else
263 length = count; 264 length = count;
264out: 265out:
265 up(&sel_sem); 266 mutex_unlock(&sel_mutex);
266 vfree(data); 267 vfree(data);
267 return length; 268 return length;
268} 269}
@@ -709,12 +710,11 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
709{ 710{
710 char *page = NULL; 711 char *page = NULL;
711 ssize_t length; 712 ssize_t length;
712 ssize_t end;
713 ssize_t ret; 713 ssize_t ret;
714 int cur_enforcing; 714 int cur_enforcing;
715 struct inode *inode; 715 struct inode *inode;
716 716
717 down(&sel_sem); 717 mutex_lock(&sel_mutex);
718 718
719 ret = -EFAULT; 719 ret = -EFAULT;
720 720
@@ -740,26 +740,9 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
740 740
741 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, 741 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
742 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); 742 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]);
743 if (length < 0) { 743 ret = simple_read_from_buffer(buf, count, ppos, page, length);
744 ret = length;
745 goto out;
746 }
747
748 if (*ppos >= length) {
749 ret = 0;
750 goto out;
751 }
752 if (count + *ppos > length)
753 count = length - *ppos;
754 end = count + *ppos;
755 if (copy_to_user(buf, (char *) page + *ppos, count)) {
756 ret = -EFAULT;
757 goto out;
758 }
759 *ppos = end;
760 ret = count;
761out: 744out:
762 up(&sel_sem); 745 mutex_unlock(&sel_mutex);
763 if (page) 746 if (page)
764 free_page((unsigned long)page); 747 free_page((unsigned long)page);
765 return ret; 748 return ret;
@@ -773,7 +756,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
773 int new_value; 756 int new_value;
774 struct inode *inode; 757 struct inode *inode;
775 758
776 down(&sel_sem); 759 mutex_lock(&sel_mutex);
777 760
778 length = task_has_security(current, SECURITY__SETBOOL); 761 length = task_has_security(current, SECURITY__SETBOOL);
779 if (length) 762 if (length)
@@ -812,7 +795,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
812 length = count; 795 length = count;
813 796
814out: 797out:
815 up(&sel_sem); 798 mutex_unlock(&sel_mutex);
816 if (page) 799 if (page)
817 free_page((unsigned long) page); 800 free_page((unsigned long) page);
818 return length; 801 return length;
@@ -831,7 +814,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
831 ssize_t length = -EFAULT; 814 ssize_t length = -EFAULT;
832 int new_value; 815 int new_value;
833 816
834 down(&sel_sem); 817 mutex_lock(&sel_mutex);
835 818
836 length = task_has_security(current, SECURITY__SETBOOL); 819 length = task_has_security(current, SECURITY__SETBOOL);
837 if (length) 820 if (length)
@@ -869,7 +852,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
869 length = count; 852 length = count;
870 853
871out: 854out:
872 up(&sel_sem); 855 mutex_unlock(&sel_mutex);
873 if (page) 856 if (page)
874 free_page((unsigned long) page); 857 free_page((unsigned long) page);
875 return length; 858 return length;
@@ -987,7 +970,7 @@ out:
987 return ret; 970 return ret;
988err: 971err:
989 kfree(values); 972 kfree(values);
990 d_genocide(dir); 973 sel_remove_bools(dir);
991 ret = -ENOMEM; 974 ret = -ENOMEM;
992 goto out; 975 goto out;
993} 976}
@@ -1168,37 +1151,38 @@ static int sel_make_avc_files(struct dentry *dir)
1168 dentry = d_alloc_name(dir, files[i].name); 1151 dentry = d_alloc_name(dir, files[i].name);
1169 if (!dentry) { 1152 if (!dentry) {
1170 ret = -ENOMEM; 1153 ret = -ENOMEM;
1171 goto err; 1154 goto out;
1172 } 1155 }
1173 1156
1174 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1157 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1175 if (!inode) { 1158 if (!inode) {
1176 ret = -ENOMEM; 1159 ret = -ENOMEM;
1177 goto err; 1160 goto out;
1178 } 1161 }
1179 inode->i_fop = files[i].ops; 1162 inode->i_fop = files[i].ops;
1180 d_add(dentry, inode); 1163 d_add(dentry, inode);
1181 } 1164 }
1182out: 1165out:
1183 return ret; 1166 return ret;
1184err:
1185 d_genocide(dir);
1186 goto out;
1187} 1167}
1188 1168
1189static int sel_make_dir(struct super_block *sb, struct dentry *dentry) 1169static int sel_make_dir(struct inode *dir, struct dentry *dentry)
1190{ 1170{
1191 int ret = 0; 1171 int ret = 0;
1192 struct inode *inode; 1172 struct inode *inode;
1193 1173
1194 inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); 1174 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1195 if (!inode) { 1175 if (!inode) {
1196 ret = -ENOMEM; 1176 ret = -ENOMEM;
1197 goto out; 1177 goto out;
1198 } 1178 }
1199 inode->i_op = &simple_dir_inode_operations; 1179 inode->i_op = &simple_dir_inode_operations;
1200 inode->i_fop = &simple_dir_operations; 1180 inode->i_fop = &simple_dir_operations;
1181 /* directory inodes start off with i_nlink == 2 (for "." entry) */
1182 inode->i_nlink++;
1201 d_add(dentry, inode); 1183 d_add(dentry, inode);
1184 /* bump link count on parent directory, too */
1185 dir->i_nlink++;
1202out: 1186out:
1203 return ret; 1187 return ret;
1204} 1188}
@@ -1207,7 +1191,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1207{ 1191{
1208 int ret; 1192 int ret;
1209 struct dentry *dentry; 1193 struct dentry *dentry;
1210 struct inode *inode; 1194 struct inode *inode, *root_inode;
1211 struct inode_security_struct *isec; 1195 struct inode_security_struct *isec;
1212 1196
1213 static struct tree_descr selinux_files[] = { 1197 static struct tree_descr selinux_files[] = {
@@ -1228,30 +1212,33 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1228 }; 1212 };
1229 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1213 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1230 if (ret) 1214 if (ret)
1231 return ret; 1215 goto err;
1216
1217 root_inode = sb->s_root->d_inode;
1232 1218
1233 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1219 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1234 if (!dentry) 1220 if (!dentry) {
1235 return -ENOMEM; 1221 ret = -ENOMEM;
1222 goto err;
1223 }
1236 1224
1237 inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO); 1225 ret = sel_make_dir(root_inode, dentry);
1238 if (!inode)
1239 goto out;
1240 inode->i_op = &simple_dir_inode_operations;
1241 inode->i_fop = &simple_dir_operations;
1242 d_add(dentry, inode);
1243 bool_dir = dentry;
1244 ret = sel_make_bools();
1245 if (ret) 1226 if (ret)
1246 goto out; 1227 goto err;
1228
1229 bool_dir = dentry;
1247 1230
1248 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1231 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1249 if (!dentry) 1232 if (!dentry) {
1250 return -ENOMEM; 1233 ret = -ENOMEM;
1234 goto err;
1235 }
1251 1236
1252 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1237 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1253 if (!inode) 1238 if (!inode) {
1254 goto out; 1239 ret = -ENOMEM;
1240 goto err;
1241 }
1255 isec = (struct inode_security_struct*)inode->i_security; 1242 isec = (struct inode_security_struct*)inode->i_security;
1256 isec->sid = SECINITSID_DEVNULL; 1243 isec->sid = SECINITSID_DEVNULL;
1257 isec->sclass = SECCLASS_CHR_FILE; 1244 isec->sclass = SECCLASS_CHR_FILE;
@@ -1262,22 +1249,23 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1262 selinux_null = dentry; 1249 selinux_null = dentry;
1263 1250
1264 dentry = d_alloc_name(sb->s_root, "avc"); 1251 dentry = d_alloc_name(sb->s_root, "avc");
1265 if (!dentry) 1252 if (!dentry) {
1266 return -ENOMEM; 1253 ret = -ENOMEM;
1254 goto err;
1255 }
1267 1256
1268 ret = sel_make_dir(sb, dentry); 1257 ret = sel_make_dir(root_inode, dentry);
1269 if (ret) 1258 if (ret)
1270 goto out; 1259 goto err;
1271 1260
1272 ret = sel_make_avc_files(dentry); 1261 ret = sel_make_avc_files(dentry);
1273 if (ret) 1262 if (ret)
1274 goto out; 1263 goto err;
1275
1276 return 0;
1277out: 1264out:
1278 dput(dentry); 1265 return ret;
1266err:
1279 printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__); 1267 printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__);
1280 return -ENOMEM; 1268 goto out;
1281} 1269}
1282 1270
1283static struct super_block *sel_get_sb(struct file_system_type *fs_type, 1271static struct super_block *sel_get_sb(struct file_system_type *fs_type,
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 8a764928ff4b..63e0b7f29cb5 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -27,7 +27,8 @@
27#include <linux/in.h> 27#include <linux/in.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <asm/semaphore.h> 30#include <linux/mutex.h>
31
31#include "flask.h" 32#include "flask.h"
32#include "avc.h" 33#include "avc.h"
33#include "avc_ss.h" 34#include "avc_ss.h"
@@ -48,9 +49,9 @@ static DEFINE_RWLOCK(policy_rwlock);
48#define POLICY_RDUNLOCK read_unlock(&policy_rwlock) 49#define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
49#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock) 50#define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
50 51
51static DECLARE_MUTEX(load_sem); 52static DEFINE_MUTEX(load_mutex);
52#define LOAD_LOCK down(&load_sem) 53#define LOAD_LOCK mutex_lock(&load_mutex)
53#define LOAD_UNLOCK up(&load_sem) 54#define LOAD_UNLOCK mutex_unlock(&load_mutex)
54 55
55static struct sidtab sidtab; 56static struct sidtab sidtab;
56struct policydb policydb; 57struct policydb policydb;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index b2af7ca496c1..dfab6c886698 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -225,6 +225,74 @@ void selinux_xfrm_state_free(struct xfrm_state *x)
225} 225}
226 226
227/* 227/*
228 * SELinux internal function to retrieve the context of a connected
229 * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security
230 * association used to connect to the remote socket.
231 *
232 * Retrieve via getsockopt SO_PEERSEC.
233 */
234u32 selinux_socket_getpeer_stream(struct sock *sk)
235{
236 struct dst_entry *dst, *dst_test;
237 u32 peer_sid = SECSID_NULL;
238
239 if (sk->sk_state != TCP_ESTABLISHED)
240 goto out;
241
242 dst = sk_dst_get(sk);
243 if (!dst)
244 goto out;
245
246 for (dst_test = dst; dst_test != 0;
247 dst_test = dst_test->child) {
248 struct xfrm_state *x = dst_test->xfrm;
249
250 if (x && selinux_authorizable_xfrm(x)) {
251 struct xfrm_sec_ctx *ctx = x->security;
252 peer_sid = ctx->ctx_sid;
253 break;
254 }
255 }
256 dst_release(dst);
257
258out:
259 return peer_sid;
260}
261
262/*
263 * SELinux internal function to retrieve the context of a UDP packet
264 * based on its security association used to connect to the remote socket.
265 *
266 * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message
267 * type SCM_SECURITY.
268 */
269u32 selinux_socket_getpeer_dgram(struct sk_buff *skb)
270{
271 struct sec_path *sp;
272
273 if (skb == NULL)
274 return SECSID_NULL;
275
276 if (skb->sk->sk_protocol != IPPROTO_UDP)
277 return SECSID_NULL;
278
279 sp = skb->sp;
280 if (sp) {
281 int i;
282
283 for (i = sp->len-1; i >= 0; i--) {
284 struct xfrm_state *x = sp->x[i].xvec;
285 if (selinux_authorizable_xfrm(x)) {
286 struct xfrm_sec_ctx *ctx = x->security;
287 return ctx->ctx_sid;
288 }
289 }
290 }
291
292 return SECSID_NULL;
293}
294
295/*
228 * LSM hook that controls access to unlabelled packets. If 296 * LSM hook that controls access to unlabelled packets. If
229 * a xfrm_state is authorizable (defined by macro) then it was 297 * a xfrm_state is authorizable (defined by macro) then it was
230 * already authorized by the IPSec process. If not, then 298 * already authorized by the IPSec process. If not, then