aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-21 22:46:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-21 22:46:00 -0500
commit78dc53c422172a317adb0776dfb687057ffa28b7 (patch)
tree7c5d15da75d769d01f6a992c24c3490b3867d5b2 /security/selinux
parent3eaded86ac3e7f00fb3eeb8162d89e9a34e42fb0 (diff)
parent62fe318256befbd1b4a6765e71d9c997f768fe79 (diff)
Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "In this patchset, we finally get an SELinux update, with Paul Moore taking over as maintainer of that code. Also a significant update for the Keys subsystem, as well as maintenance updates to Smack, IMA, TPM, and Apparmor" and since I wanted to know more about the updates to key handling, here's the explanation from David Howells on that: "Okay. There are a number of separate bits. I'll go over the big bits and the odd important other bit, most of the smaller bits are just fixes and cleanups. If you want the small bits accounting for, I can do that too. (1) Keyring capacity expansion. KEYS: Consolidate the concept of an 'index key' for key access KEYS: Introduce a search context structure KEYS: Search for auth-key by name rather than target key ID Add a generic associative array implementation. KEYS: Expand the capacity of a keyring Several of the patches are providing an expansion of the capacity of a keyring. Currently, the maximum size of a keyring payload is one page. Subtract a small header and then divide up into pointers, that only gives you ~500 pointers on an x86_64 box. However, since the NFS idmapper uses a keyring to store ID mapping data, that has proven to be insufficient to the cause. Whatever data structure I use to handle the keyring payload, it can only store pointers to keys, not the keys themselves because several keyrings may point to a single key. This precludes inserting, say, and rb_node struct into the key struct for this purpose. I could make an rbtree of records such that each record has an rb_node and a key pointer, but that would use four words of space per key stored in the keyring. It would, however, be able to use much existing code. I selected instead a non-rebalancing radix-tree type approach as that could have a better space-used/key-pointer ratio. I could have used the radix tree implementation that we already have and insert keys into it by their serial numbers, but that means any sort of search must iterate over the whole radix tree. Further, its nodes are a bit on the capacious side for what I want - especially given that key serial numbers are randomly allocated, thus leaving a lot of empty space in the tree. So what I have is an associative array that internally is a radix-tree with 16 pointers per node where the index key is constructed from the key type pointer and the key description. This means that an exact lookup by type+description is very fast as this tells us how to navigate directly to the target key. I made the data structure general in lib/assoc_array.c as far as it is concerned, its index key is just a sequence of bits that leads to a pointer. It's possible that someone else will be able to make use of it also. FS-Cache might, for example. (2) Mark keys as 'trusted' and keyrings as 'trusted only'. KEYS: verify a certificate is signed by a 'trusted' key KEYS: Make the system 'trusted' keyring viewable by userspace KEYS: Add a 'trusted' flag and a 'trusted only' flag KEYS: Separate the kernel signature checking keyring from module signing These patches allow keys carrying asymmetric public keys to be marked as being 'trusted' and allow keyrings to be marked as only permitting the addition or linkage of trusted keys. Keys loaded from hardware during kernel boot or compiled into the kernel during build are marked as being trusted automatically. New keys can be loaded at runtime with add_key(). They are checked against the system keyring contents and if their signatures can be validated with keys that are already marked trusted, then they are marked trusted also and can thus be added into the master keyring. Patches from Mimi Zohar make this usable with the IMA keyrings also. (3) Remove the date checks on the key used to validate a module signature. X.509: Remove certificate date checks It's not reasonable to reject a signature just because the key that it was generated with is no longer valid datewise - especially if the kernel hasn't yet managed to set the system clock when the first module is loaded - so just remove those checks. (4) Make it simpler to deal with additional X.509 being loaded into the kernel. KEYS: Load *.x509 files into kernel keyring KEYS: Have make canonicalise the paths of the X.509 certs better to deduplicate The builder of the kernel now just places files with the extension ".x509" into the kernel source or build trees and they're concatenated by the kernel build and stuffed into the appropriate section. (5) Add support for userspace kerberos to use keyrings. KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches KEYS: Implement a big key type that can save to tmpfs Fedora went to, by default, storing kerberos tickets and tokens in tmpfs. We looked at storing it in keyrings instead as that confers certain advantages such as tickets being automatically deleted after a certain amount of time and the ability for the kernel to get at these tokens more easily. To make this work, two things were needed: (a) A way for the tickets to persist beyond the lifetime of all a user's sessions so that cron-driven processes can still use them. The problem is that a user's session keyrings are deleted when the session that spawned them logs out and the user's user keyring is deleted when the UID is deleted (typically when the last log out happens), so neither of these places is suitable. I've added a system keyring into which a 'persistent' keyring is created for each UID on request. Each time a user requests their persistent keyring, the expiry time on it is set anew. If the user doesn't ask for it for, say, three days, the keyring is automatically expired and garbage collected using the existing gc. All the kerberos tokens it held are then also gc'd. (b) A key type that can hold really big tickets (up to 1MB in size). The problem is that Active Directory can return huge tickets with lots of auxiliary data attached. We don't, however, want to eat up huge tracts of unswappable kernel space for this, so if the ticket is greater than a certain size, we create a swappable shmem file and dump the contents in there and just live with the fact we then have an inode and a dentry overhead. If the ticket is smaller than that, we slap it in a kmalloc()'d buffer" * 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (121 commits) KEYS: Fix keyring content gc scanner KEYS: Fix error handling in big_key instantiation KEYS: Fix UID check in keyctl_get_persistent() KEYS: The RSA public key algorithm needs to select MPILIB ima: define '_ima' as a builtin 'trusted' keyring ima: extend the measurement list to include the file signature kernel/system_certificate.S: use real contents instead of macro GLOBAL() KEYS: fix error return code in big_key_instantiate() KEYS: Fix keyring quota misaccounting on key replacement and unlink KEYS: Fix a race between negating a key and reading the error set KEYS: Make BIG_KEYS boolean apparmor: remove the "task" arg from may_change_ptraced_domain() apparmor: remove parent task info from audit logging apparmor: remove tsk field from the apparmor_audit_struct apparmor: fix capability to not use the current task, during reporting Smack: Ptrace access check mode ima: provide hash algo info in the xattr ima: enable support for larger default filedata hash algorithms ima: define kernel parameter 'ima_template=' to change configured default ima: add Kconfig default measurement list template ...
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c146
-rw-r--r--security/selinux/include/objsec.h4
-rw-r--r--security/selinux/include/security.h13
-rw-r--r--security/selinux/include/xfrm.h45
-rw-r--r--security/selinux/netlabel.c6
-rw-r--r--security/selinux/netnode.c2
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/ebitmap.c20
-rw-r--r--security/selinux/ss/ebitmap.h10
-rw-r--r--security/selinux/ss/mls.c22
-rw-r--r--security/selinux/ss/mls_types.h2
-rw-r--r--security/selinux/ss/policydb.c3
-rw-r--r--security/selinux/ss/services.c66
-rw-r--r--security/selinux/xfrm.c453
14 files changed, 417 insertions, 379 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c540795fb3f2..794c3ca49eac 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -95,7 +95,9 @@
95#include "audit.h" 95#include "audit.h"
96#include "avc_ss.h" 96#include "avc_ss.h"
97 97
98#define NUM_SEL_MNT_OPTS 5 98#define SB_TYPE_FMT "%s%s%s"
99#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
100#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
99 101
100extern struct security_operations *security_ops; 102extern struct security_operations *security_ops;
101 103
@@ -139,12 +141,28 @@ static struct kmem_cache *sel_inode_cache;
139 * This function checks the SECMARK reference counter to see if any SECMARK 141 * This function checks the SECMARK reference counter to see if any SECMARK
140 * targets are currently configured, if the reference counter is greater than 142 * targets are currently configured, if the reference counter is greater than
141 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is 143 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
142 * enabled, false (0) if SECMARK is disabled. 144 * enabled, false (0) if SECMARK is disabled. If the always_check_network
145 * policy capability is enabled, SECMARK is always considered enabled.
143 * 146 *
144 */ 147 */
145static int selinux_secmark_enabled(void) 148static int selinux_secmark_enabled(void)
146{ 149{
147 return (atomic_read(&selinux_secmark_refcount) > 0); 150 return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
151}
152
153/**
154 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
155 *
156 * Description:
157 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
158 * (1) if any are enabled or false (0) if neither are enabled. If the
159 * always_check_network policy capability is enabled, peer labeling
160 * is always considered enabled.
161 *
162 */
163static int selinux_peerlbl_enabled(void)
164{
165 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
148} 166}
149 167
150/* 168/*
@@ -309,8 +327,11 @@ enum {
309 Opt_defcontext = 3, 327 Opt_defcontext = 3,
310 Opt_rootcontext = 4, 328 Opt_rootcontext = 4,
311 Opt_labelsupport = 5, 329 Opt_labelsupport = 5,
330 Opt_nextmntopt = 6,
312}; 331};
313 332
333#define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1)
334
314static const match_table_t tokens = { 335static const match_table_t tokens = {
315 {Opt_context, CONTEXT_STR "%s"}, 336 {Opt_context, CONTEXT_STR "%s"},
316 {Opt_fscontext, FSCONTEXT_STR "%s"}, 337 {Opt_fscontext, FSCONTEXT_STR "%s"},
@@ -355,6 +376,29 @@ static int may_context_mount_inode_relabel(u32 sid,
355 return rc; 376 return rc;
356} 377}
357 378
379static int selinux_is_sblabel_mnt(struct super_block *sb)
380{
381 struct superblock_security_struct *sbsec = sb->s_security;
382
383 if (sbsec->behavior == SECURITY_FS_USE_XATTR ||
384 sbsec->behavior == SECURITY_FS_USE_TRANS ||
385 sbsec->behavior == SECURITY_FS_USE_TASK)
386 return 1;
387
388 /* Special handling for sysfs. Is genfs but also has setxattr handler*/
389 if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
390 return 1;
391
392 /*
393 * Special handling for rootfs. Is genfs but supports
394 * setting SELinux context on in-core inodes.
395 */
396 if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
397 return 1;
398
399 return 0;
400}
401
358static int sb_finish_set_opts(struct super_block *sb) 402static int sb_finish_set_opts(struct super_block *sb)
359{ 403{
360 struct superblock_security_struct *sbsec = sb->s_security; 404 struct superblock_security_struct *sbsec = sb->s_security;
@@ -369,8 +413,8 @@ static int sb_finish_set_opts(struct super_block *sb)
369 the first boot of the SELinux kernel before we have 413 the first boot of the SELinux kernel before we have
370 assigned xattr values to the filesystem. */ 414 assigned xattr values to the filesystem. */
371 if (!root_inode->i_op->getxattr) { 415 if (!root_inode->i_op->getxattr) {
372 printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " 416 printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
373 "xattr support\n", sb->s_id, sb->s_type->name); 417 "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
374 rc = -EOPNOTSUPP; 418 rc = -EOPNOTSUPP;
375 goto out; 419 goto out;
376 } 420 }
@@ -378,35 +422,27 @@ static int sb_finish_set_opts(struct super_block *sb)
378 if (rc < 0 && rc != -ENODATA) { 422 if (rc < 0 && rc != -ENODATA) {
379 if (rc == -EOPNOTSUPP) 423 if (rc == -EOPNOTSUPP)
380 printk(KERN_WARNING "SELinux: (dev %s, type " 424 printk(KERN_WARNING "SELinux: (dev %s, type "
381 "%s) has no security xattr handler\n", 425 SB_TYPE_FMT") has no security xattr handler\n",
382 sb->s_id, sb->s_type->name); 426 sb->s_id, SB_TYPE_ARGS(sb));
383 else 427 else
384 printk(KERN_WARNING "SELinux: (dev %s, type " 428 printk(KERN_WARNING "SELinux: (dev %s, type "
385 "%s) getxattr errno %d\n", sb->s_id, 429 SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
386 sb->s_type->name, -rc); 430 SB_TYPE_ARGS(sb), -rc);
387 goto out; 431 goto out;
388 } 432 }
389 } 433 }
390 434
391 sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
392
393 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 435 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
394 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", 436 printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
395 sb->s_id, sb->s_type->name); 437 sb->s_id, SB_TYPE_ARGS(sb));
396 else 438 else
397 printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", 439 printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
398 sb->s_id, sb->s_type->name, 440 sb->s_id, SB_TYPE_ARGS(sb),
399 labeling_behaviors[sbsec->behavior-1]); 441 labeling_behaviors[sbsec->behavior-1]);
400 442
401 if (sbsec->behavior == SECURITY_FS_USE_GENFS || 443 sbsec->flags |= SE_SBINITIALIZED;
402 sbsec->behavior == SECURITY_FS_USE_MNTPOINT || 444 if (selinux_is_sblabel_mnt(sb))
403 sbsec->behavior == SECURITY_FS_USE_NONE || 445 sbsec->flags |= SBLABEL_MNT;
404 sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
405 sbsec->flags &= ~SE_SBLABELSUPP;
406
407 /* Special handling for sysfs. Is genfs but also has setxattr handler*/
408 if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
409 sbsec->flags |= SE_SBLABELSUPP;
410 446
411 /* Initialize the root inode. */ 447 /* Initialize the root inode. */
412 rc = inode_doinit_with_dentry(root_inode, root); 448 rc = inode_doinit_with_dentry(root_inode, root);
@@ -460,15 +496,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
460 if (!ss_initialized) 496 if (!ss_initialized)
461 return -EINVAL; 497 return -EINVAL;
462 498
499 /* make sure we always check enough bits to cover the mask */
500 BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
501
463 tmp = sbsec->flags & SE_MNTMASK; 502 tmp = sbsec->flags & SE_MNTMASK;
464 /* count the number of mount options for this sb */ 503 /* count the number of mount options for this sb */
465 for (i = 0; i < 8; i++) { 504 for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
466 if (tmp & 0x01) 505 if (tmp & 0x01)
467 opts->num_mnt_opts++; 506 opts->num_mnt_opts++;
468 tmp >>= 1; 507 tmp >>= 1;
469 } 508 }
470 /* Check if the Label support flag is set */ 509 /* Check if the Label support flag is set */
471 if (sbsec->flags & SE_SBLABELSUPP) 510 if (sbsec->flags & SBLABEL_MNT)
472 opts->num_mnt_opts++; 511 opts->num_mnt_opts++;
473 512
474 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 513 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
@@ -515,9 +554,9 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
515 opts->mnt_opts[i] = context; 554 opts->mnt_opts[i] = context;
516 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 555 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
517 } 556 }
518 if (sbsec->flags & SE_SBLABELSUPP) { 557 if (sbsec->flags & SBLABEL_MNT) {
519 opts->mnt_opts[i] = NULL; 558 opts->mnt_opts[i] = NULL;
520 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP; 559 opts->mnt_opts_flags[i++] = SBLABEL_MNT;
521 } 560 }
522 561
523 BUG_ON(i != opts->num_mnt_opts); 562 BUG_ON(i != opts->num_mnt_opts);
@@ -561,7 +600,6 @@ static int selinux_set_mnt_opts(struct super_block *sb,
561 const struct cred *cred = current_cred(); 600 const struct cred *cred = current_cred();
562 int rc = 0, i; 601 int rc = 0, i;
563 struct superblock_security_struct *sbsec = sb->s_security; 602 struct superblock_security_struct *sbsec = sb->s_security;
564 const char *name = sb->s_type->name;
565 struct inode *inode = sbsec->sb->s_root->d_inode; 603 struct inode *inode = sbsec->sb->s_root->d_inode;
566 struct inode_security_struct *root_isec = inode->i_security; 604 struct inode_security_struct *root_isec = inode->i_security;
567 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 605 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -614,14 +652,14 @@ static int selinux_set_mnt_opts(struct super_block *sb,
614 for (i = 0; i < num_opts; i++) { 652 for (i = 0; i < num_opts; i++) {
615 u32 sid; 653 u32 sid;
616 654
617 if (flags[i] == SE_SBLABELSUPP) 655 if (flags[i] == SBLABEL_MNT)
618 continue; 656 continue;
619 rc = security_context_to_sid(mount_options[i], 657 rc = security_context_to_sid(mount_options[i],
620 strlen(mount_options[i]), &sid); 658 strlen(mount_options[i]), &sid);
621 if (rc) { 659 if (rc) {
622 printk(KERN_WARNING "SELinux: security_context_to_sid" 660 printk(KERN_WARNING "SELinux: security_context_to_sid"
623 "(%s) failed for (dev %s, type %s) errno=%d\n", 661 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
624 mount_options[i], sb->s_id, name, rc); 662 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
625 goto out; 663 goto out;
626 } 664 }
627 switch (flags[i]) { 665 switch (flags[i]) {
@@ -685,9 +723,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
685 * Determine the labeling behavior to use for this 723 * Determine the labeling behavior to use for this
686 * filesystem type. 724 * filesystem type.
687 */ 725 */
688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? 726 rc = security_fs_use(sb);
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) { 727 if (rc) {
692 printk(KERN_WARNING 728 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n", 729 "%s: security_fs_use(%s) returned %d\n",
@@ -770,7 +806,8 @@ out:
770out_double_mount: 806out_double_mount:
771 rc = -EINVAL; 807 rc = -EINVAL;
772 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " 808 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different "
773 "security settings for (dev %s, type %s)\n", sb->s_id, name); 809 "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
810 SB_TYPE_ARGS(sb));
774 goto out; 811 goto out;
775} 812}
776 813
@@ -1037,7 +1074,7 @@ static void selinux_write_opts(struct seq_file *m,
1037 case DEFCONTEXT_MNT: 1074 case DEFCONTEXT_MNT:
1038 prefix = DEFCONTEXT_STR; 1075 prefix = DEFCONTEXT_STR;
1039 break; 1076 break;
1040 case SE_SBLABELSUPP: 1077 case SBLABEL_MNT:
1041 seq_putc(m, ','); 1078 seq_putc(m, ',');
1042 seq_puts(m, LABELSUPP_STR); 1079 seq_puts(m, LABELSUPP_STR);
1043 continue; 1080 continue;
@@ -1649,7 +1686,7 @@ static int may_create(struct inode *dir,
1649 if (rc) 1686 if (rc)
1650 return rc; 1687 return rc;
1651 1688
1652 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1689 if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
1653 rc = security_transition_sid(sid, dsec->sid, tclass, 1690 rc = security_transition_sid(sid, dsec->sid, tclass,
1654 &dentry->d_name, &newsid); 1691 &dentry->d_name, &newsid);
1655 if (rc) 1692 if (rc)
@@ -2437,14 +2474,14 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2437 u32 sid; 2474 u32 sid;
2438 size_t len; 2475 size_t len;
2439 2476
2440 if (flags[i] == SE_SBLABELSUPP) 2477 if (flags[i] == SBLABEL_MNT)
2441 continue; 2478 continue;
2442 len = strlen(mount_options[i]); 2479 len = strlen(mount_options[i]);
2443 rc = security_context_to_sid(mount_options[i], len, &sid); 2480 rc = security_context_to_sid(mount_options[i], len, &sid);
2444 if (rc) { 2481 if (rc) {
2445 printk(KERN_WARNING "SELinux: security_context_to_sid" 2482 printk(KERN_WARNING "SELinux: security_context_to_sid"
2446 "(%s) failed for (dev %s, type %s) errno=%d\n", 2483 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
2447 mount_options[i], sb->s_id, sb->s_type->name, rc); 2484 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
2448 goto out_free_opts; 2485 goto out_free_opts;
2449 } 2486 }
2450 rc = -EINVAL; 2487 rc = -EINVAL;
@@ -2482,8 +2519,8 @@ out_free_secdata:
2482 return rc; 2519 return rc;
2483out_bad_option: 2520out_bad_option:
2484 printk(KERN_WARNING "SELinux: unable to change security options " 2521 printk(KERN_WARNING "SELinux: unable to change security options "
2485 "during remount (dev %s, type=%s)\n", sb->s_id, 2522 "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
2486 sb->s_type->name); 2523 SB_TYPE_ARGS(sb));
2487 goto out_free_opts; 2524 goto out_free_opts;
2488} 2525}
2489 2526
@@ -2606,7 +2643,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2606 if ((sbsec->flags & SE_SBINITIALIZED) && 2643 if ((sbsec->flags & SE_SBINITIALIZED) &&
2607 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) 2644 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2608 newsid = sbsec->mntpoint_sid; 2645 newsid = sbsec->mntpoint_sid;
2609 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2646 else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
2610 rc = security_transition_sid(sid, dsec->sid, 2647 rc = security_transition_sid(sid, dsec->sid,
2611 inode_mode_to_security_class(inode->i_mode), 2648 inode_mode_to_security_class(inode->i_mode),
2612 qstr, &newsid); 2649 qstr, &newsid);
@@ -2628,7 +2665,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2628 isec->initialized = 1; 2665 isec->initialized = 1;
2629 } 2666 }
2630 2667
2631 if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP)) 2668 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
2632 return -EOPNOTSUPP; 2669 return -EOPNOTSUPP;
2633 2670
2634 if (name) 2671 if (name)
@@ -2830,7 +2867,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2830 return selinux_inode_setotherxattr(dentry, name); 2867 return selinux_inode_setotherxattr(dentry, name);
2831 2868
2832 sbsec = inode->i_sb->s_security; 2869 sbsec = inode->i_sb->s_security;
2833 if (!(sbsec->flags & SE_SBLABELSUPP)) 2870 if (!(sbsec->flags & SBLABEL_MNT))
2834 return -EOPNOTSUPP; 2871 return -EOPNOTSUPP;
2835 2872
2836 if (!inode_owner_or_capable(inode)) 2873 if (!inode_owner_or_capable(inode))
@@ -3791,8 +3828,12 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3791 u32 nlbl_sid; 3828 u32 nlbl_sid;
3792 u32 nlbl_type; 3829 u32 nlbl_type;
3793 3830
3794 selinux_skb_xfrm_sid(skb, &xfrm_sid); 3831 err = selinux_skb_xfrm_sid(skb, &xfrm_sid);
3795 selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); 3832 if (unlikely(err))
3833 return -EACCES;
3834 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
3835 if (unlikely(err))
3836 return -EACCES;
3796 3837
3797 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid); 3838 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
3798 if (unlikely(err)) { 3839 if (unlikely(err)) {
@@ -4246,7 +4287,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4246 return selinux_sock_rcv_skb_compat(sk, skb, family); 4287 return selinux_sock_rcv_skb_compat(sk, skb, family);
4247 4288
4248 secmark_active = selinux_secmark_enabled(); 4289 secmark_active = selinux_secmark_enabled();
4249 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4290 peerlbl_active = selinux_peerlbl_enabled();
4250 if (!secmark_active && !peerlbl_active) 4291 if (!secmark_active && !peerlbl_active)
4251 return 0; 4292 return 0;
4252 4293
@@ -4628,7 +4669,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4628 4669
4629 secmark_active = selinux_secmark_enabled(); 4670 secmark_active = selinux_secmark_enabled();
4630 netlbl_active = netlbl_enabled(); 4671 netlbl_active = netlbl_enabled();
4631 peerlbl_active = netlbl_active || selinux_xfrm_enabled(); 4672 peerlbl_active = selinux_peerlbl_enabled();
4632 if (!secmark_active && !peerlbl_active) 4673 if (!secmark_active && !peerlbl_active)
4633 return NF_ACCEPT; 4674 return NF_ACCEPT;
4634 4675
@@ -4780,7 +4821,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4780 return NF_ACCEPT; 4821 return NF_ACCEPT;
4781#endif 4822#endif
4782 secmark_active = selinux_secmark_enabled(); 4823 secmark_active = selinux_secmark_enabled();
4783 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4824 peerlbl_active = selinux_peerlbl_enabled();
4784 if (!secmark_active && !peerlbl_active) 4825 if (!secmark_active && !peerlbl_active)
4785 return NF_ACCEPT; 4826 return NF_ACCEPT;
4786 4827
@@ -5784,7 +5825,8 @@ static struct security_operations selinux_ops = {
5784 .xfrm_policy_clone_security = selinux_xfrm_policy_clone, 5825 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
5785 .xfrm_policy_free_security = selinux_xfrm_policy_free, 5826 .xfrm_policy_free_security = selinux_xfrm_policy_free,
5786 .xfrm_policy_delete_security = selinux_xfrm_policy_delete, 5827 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
5787 .xfrm_state_alloc_security = selinux_xfrm_state_alloc, 5828 .xfrm_state_alloc = selinux_xfrm_state_alloc,
5829 .xfrm_state_alloc_acquire = selinux_xfrm_state_alloc_acquire,
5788 .xfrm_state_free_security = selinux_xfrm_state_free, 5830 .xfrm_state_free_security = selinux_xfrm_state_free,
5789 .xfrm_state_delete_security = selinux_xfrm_state_delete, 5831 .xfrm_state_delete_security = selinux_xfrm_state_delete,
5790 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 5832 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index aa47bcabb5f6..b1dfe1049450 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -58,8 +58,8 @@ struct superblock_security_struct {
58 u32 sid; /* SID of file system superblock */ 58 u32 sid; /* SID of file system superblock */
59 u32 def_sid; /* default SID for labeling */ 59 u32 def_sid; /* default SID for labeling */
60 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ 60 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
61 unsigned int behavior; /* labeling behavior */ 61 unsigned short behavior; /* labeling behavior */
62 unsigned char flags; /* which mount options were specified */ 62 unsigned short flags; /* which mount options were specified */
63 struct mutex lock; 63 struct mutex lock;
64 struct list_head isec_head; 64 struct list_head isec_head;
65 spinlock_t isec_lock; 65 spinlock_t isec_lock;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8fd8e18ea340..fe341ae37004 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -45,14 +45,15 @@
45/* Mask for just the mount related flags */ 45/* Mask for just the mount related flags */
46#define SE_MNTMASK 0x0f 46#define SE_MNTMASK 0x0f
47/* Super block security struct flags for mount options */ 47/* Super block security struct flags for mount options */
48/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */
48#define CONTEXT_MNT 0x01 49#define CONTEXT_MNT 0x01
49#define FSCONTEXT_MNT 0x02 50#define FSCONTEXT_MNT 0x02
50#define ROOTCONTEXT_MNT 0x04 51#define ROOTCONTEXT_MNT 0x04
51#define DEFCONTEXT_MNT 0x08 52#define DEFCONTEXT_MNT 0x08
53#define SBLABEL_MNT 0x10
52/* Non-mount related flags */ 54/* Non-mount related flags */
53#define SE_SBINITIALIZED 0x10 55#define SE_SBINITIALIZED 0x0100
54#define SE_SBPROC 0x20 56#define SE_SBPROC 0x0200
55#define SE_SBLABELSUPP 0x40
56 57
57#define CONTEXT_STR "context=" 58#define CONTEXT_STR "context="
58#define FSCONTEXT_STR "fscontext=" 59#define FSCONTEXT_STR "fscontext="
@@ -68,12 +69,15 @@ extern int selinux_enabled;
68enum { 69enum {
69 POLICYDB_CAPABILITY_NETPEER, 70 POLICYDB_CAPABILITY_NETPEER,
70 POLICYDB_CAPABILITY_OPENPERM, 71 POLICYDB_CAPABILITY_OPENPERM,
72 POLICYDB_CAPABILITY_REDHAT1,
73 POLICYDB_CAPABILITY_ALWAYSNETWORK,
71 __POLICYDB_CAPABILITY_MAX 74 __POLICYDB_CAPABILITY_MAX
72}; 75};
73#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 76#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
74 77
75extern int selinux_policycap_netpeer; 78extern int selinux_policycap_netpeer;
76extern int selinux_policycap_openperm; 79extern int selinux_policycap_openperm;
80extern int selinux_policycap_alwaysnetwork;
77 81
78/* 82/*
79 * type_datum properties 83 * type_datum properties
@@ -172,8 +176,7 @@ int security_get_allow_unknown(void);
172#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ 176#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
173#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ 177#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
174 178
175int security_fs_use(const char *fstype, unsigned int *behavior, 179int security_fs_use(struct super_block *sb);
176 u32 *sid);
177 180
178int security_genfs_sid(const char *fstype, char *name, u16 sclass, 181int security_genfs_sid(const char *fstype, char *name, u16 sclass,
179 u32 *sid); 182 u32 *sid);
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 6713f04e30ba..0dec76c64cf5 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -10,29 +10,21 @@
10#include <net/flow.h> 10#include <net/flow.h>
11 11
12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
13 struct xfrm_user_sec_ctx *sec_ctx); 13 struct xfrm_user_sec_ctx *uctx);
14int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 14int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
15 struct xfrm_sec_ctx **new_ctxp); 15 struct xfrm_sec_ctx **new_ctxp);
16void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); 16void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
17int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); 17int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
18int selinux_xfrm_state_alloc(struct xfrm_state *x, 18int selinux_xfrm_state_alloc(struct xfrm_state *x,
19 struct xfrm_user_sec_ctx *sec_ctx, u32 secid); 19 struct xfrm_user_sec_ctx *uctx);
20int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
21 struct xfrm_sec_ctx *polsec, u32 secid);
20void selinux_xfrm_state_free(struct xfrm_state *x); 22void selinux_xfrm_state_free(struct xfrm_state *x);
21int selinux_xfrm_state_delete(struct xfrm_state *x); 23int selinux_xfrm_state_delete(struct xfrm_state *x);
22int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); 24int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
23int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 25int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
24 struct xfrm_policy *xp, const struct flowi *fl); 26 struct xfrm_policy *xp,
25 27 const struct flowi *fl);
26/*
27 * Extract the security blob from the sock (it's actually on the socket)
28 */
29static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
30{
31 if (!sk->sk_socket)
32 return NULL;
33
34 return SOCK_INODE(sk->sk_socket)->i_security;
35}
36 28
37#ifdef CONFIG_SECURITY_NETWORK_XFRM 29#ifdef CONFIG_SECURITY_NETWORK_XFRM
38extern atomic_t selinux_xfrm_refcount; 30extern atomic_t selinux_xfrm_refcount;
@@ -42,10 +34,10 @@ static inline int selinux_xfrm_enabled(void)
42 return (atomic_read(&selinux_xfrm_refcount) > 0); 34 return (atomic_read(&selinux_xfrm_refcount) > 0);
43} 35}
44 36
45int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, 37int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
46 struct common_audit_data *ad); 38 struct common_audit_data *ad);
47int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 39int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
48 struct common_audit_data *ad, u8 proto); 40 struct common_audit_data *ad, u8 proto);
49int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); 41int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
50 42
51static inline void selinux_xfrm_notify_policyload(void) 43static inline void selinux_xfrm_notify_policyload(void)
@@ -64,19 +56,21 @@ static inline int selinux_xfrm_enabled(void)
64 return 0; 56 return 0;
65} 57}
66 58
67static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, 59static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
68 struct common_audit_data *ad) 60 struct common_audit_data *ad)
69{ 61{
70 return 0; 62 return 0;
71} 63}
72 64
73static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 65static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
74 struct common_audit_data *ad, u8 proto) 66 struct common_audit_data *ad,
67 u8 proto)
75{ 68{
76 return 0; 69 return 0;
77} 70}
78 71
79static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) 72static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid,
73 int ckall)
80{ 74{
81 *sid = SECSID_NULL; 75 *sid = SECSID_NULL;
82 return 0; 76 return 0;
@@ -87,10 +81,9 @@ static inline void selinux_xfrm_notify_policyload(void)
87} 81}
88#endif 82#endif
89 83
90static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) 84static inline int selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
91{ 85{
92 int err = selinux_xfrm_decode_session(skb, sid, 0); 86 return selinux_xfrm_decode_session(skb, sid, 0);
93 BUG_ON(err);
94} 87}
95 88
96#endif /* _SELINUX_XFRM_H_ */ 89#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index da4b8b233280..6235d052338b 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
442 sksec->nlbl_state != NLBL_CONNLABELED) 442 sksec->nlbl_state != NLBL_CONNLABELED)
443 return 0; 443 return 0;
444 444
445 local_bh_disable(); 445 lock_sock(sk);
446 bh_lock_sock_nested(sk);
447 446
448 /* connected sockets are allowed to disconnect when the address family 447 /* connected sockets are allowed to disconnect when the address family
449 * is set to AF_UNSPEC, if that is what is happening we want to reset 448 * is set to AF_UNSPEC, if that is what is happening we want to reset
@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
464 sksec->nlbl_state = NLBL_CONNLABELED; 463 sksec->nlbl_state = NLBL_CONNLABELED;
465 464
466socket_connect_return: 465socket_connect_return:
467 bh_unlock_sock(sk); 466 release_sock(sk);
468 local_bh_enable();
469 return rc; 467 return rc;
470} 468}
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index c5454c0477c3..03a72c32afd7 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -166,6 +166,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
166 break; 166 break;
167 default: 167 default:
168 BUG(); 168 BUG();
169 return;
169 } 170 }
170 171
171 /* we need to impose a limit on the growth of the hash table so check 172 /* we need to impose a limit on the growth of the hash table so check
@@ -225,6 +226,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
225 break; 226 break;
226 default: 227 default:
227 BUG(); 228 BUG();
229 ret = -EINVAL;
228 } 230 }
229 if (ret != 0) 231 if (ret != 0)
230 goto out; 232 goto out;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index ff427733c290..5122affe06a8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -44,7 +44,9 @@
44/* Policy capability filenames */ 44/* Policy capability filenames */
45static char *policycap_names[] = { 45static char *policycap_names[] = {
46 "network_peer_controls", 46 "network_peer_controls",
47 "open_perms" 47 "open_perms",
48 "redhat1",
49 "always_check_network"
48}; 50};
49 51
50unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 52unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 30f119b1d1ec..820313a04d49 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -213,7 +213,12 @@ netlbl_import_failure:
213} 213}
214#endif /* CONFIG_NETLABEL */ 214#endif /* CONFIG_NETLABEL */
215 215
216int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 216/*
217 * Check to see if all the bits set in e2 are also set in e1. Optionally,
218 * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
219 * last_e2bit.
220 */
221int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
217{ 222{
218 struct ebitmap_node *n1, *n2; 223 struct ebitmap_node *n1, *n2;
219 int i; 224 int i;
@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
223 228
224 n1 = e1->node; 229 n1 = e1->node;
225 n2 = e2->node; 230 n2 = e2->node;
231
226 while (n1 && n2 && (n1->startbit <= n2->startbit)) { 232 while (n1 && n2 && (n1->startbit <= n2->startbit)) {
227 if (n1->startbit < n2->startbit) { 233 if (n1->startbit < n2->startbit) {
228 n1 = n1->next; 234 n1 = n1->next;
229 continue; 235 continue;
230 } 236 }
231 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 237 for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
238 i--; /* Skip trailing NULL map entries */
239 if (last_e2bit && (i >= 0)) {
240 u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
241 __fls(n2->maps[i]);
242 if (lastsetbit > last_e2bit)
243 return 0;
244 }
245
246 while (i >= 0) {
232 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) 247 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
233 return 0; 248 return 0;
249 i--;
234 } 250 }
235 251
236 n1 = n1->next; 252 n1 = n1->next;
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 922f8afa89dd..712c8a7b8e8b 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -16,7 +16,13 @@
16 16
17#include <net/netlabel.h> 17#include <net/netlabel.h>
18 18
19#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \ 19#ifdef CONFIG_64BIT
20#define EBITMAP_NODE_SIZE 64
21#else
22#define EBITMAP_NODE_SIZE 32
23#endif
24
25#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\
20 / sizeof(unsigned long)) 26 / sizeof(unsigned long))
21#define EBITMAP_UNIT_SIZE BITS_PER_LONG 27#define EBITMAP_UNIT_SIZE BITS_PER_LONG
22#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) 28#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
117 123
118int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 124int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
119int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 125int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
120int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 126int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit);
121int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); 127int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
122int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 128int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
123void ebitmap_destroy(struct ebitmap *e); 129void ebitmap_destroy(struct ebitmap *e);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 40de8d3f208e..c85bc1ec040c 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context,
160int mls_level_isvalid(struct policydb *p, struct mls_level *l) 160int mls_level_isvalid(struct policydb *p, struct mls_level *l)
161{ 161{
162 struct level_datum *levdatum; 162 struct level_datum *levdatum;
163 struct ebitmap_node *node;
164 int i;
165 163
166 if (!l->sens || l->sens > p->p_levels.nprim) 164 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 165 return 0;
@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
170 if (!levdatum) 168 if (!levdatum)
171 return 0; 169 return 0;
172 170
173 ebitmap_for_each_positive_bit(&l->cat, node, i) { 171 /*
174 if (i > p->p_cats.nprim) 172 * Return 1 iff all the bits set in l->cat are also be set in
175 return 0; 173 * levdatum->level->cat and no bit in l->cat is larger than
176 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 174 * p->p_cats.nprim.
177 /* 175 */
178 * Category may not be associated with 176 return ebitmap_contains(&levdatum->level->cat, &l->cat,
179 * sensitivity. 177 p->p_cats.nprim);
180 */
181 return 0;
182 }
183 }
184
185 return 1;
186} 178}
187 179
188int mls_range_isvalid(struct policydb *p, struct mls_range *r) 180int mls_range_isvalid(struct policydb *p, struct mls_range *r)
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index 03bed52a8052..e93648774137 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
36{ 36{
37 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
38 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat, 0));
39} 39}
40 40
41#define mls_level_incomp(l1, l2) \ 41#define mls_level_incomp(l1, l2) \
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c8adde3aff8f..f6195ebde3c9 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
3203 3203
3204static int range_write(struct policydb *p, void *fp) 3204static int range_write(struct policydb *p, void *fp)
3205{ 3205{
3206 size_t nel;
3207 __le32 buf[1]; 3206 __le32 buf[1];
3208 int rc; 3207 int rc, nel;
3209 struct policy_data pd; 3208 struct policy_data pd;
3210 3209
3211 pd.p = p; 3210 pd.p = p;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b4feecc3fe01..ee470a0b5c27 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -72,6 +72,7 @@
72 72
73int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 74int selinux_policycap_openperm;
75int selinux_policycap_alwaysnetwork;
75 76
76static DEFINE_RWLOCK(policy_rwlock); 77static DEFINE_RWLOCK(policy_rwlock);
77 78
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
1812 POLICYDB_CAPABILITY_NETPEER); 1813 POLICYDB_CAPABILITY_NETPEER);
1813 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 1814 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
1814 POLICYDB_CAPABILITY_OPENPERM); 1815 POLICYDB_CAPABILITY_OPENPERM);
1816 selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
1817 POLICYDB_CAPABILITY_ALWAYSNETWORK);
1815} 1818}
1816 1819
1817static int security_preserve_bools(struct policydb *p); 1820static int security_preserve_bools(struct policydb *p);
@@ -2323,43 +2326,74 @@ out:
2323 2326
2324/** 2327/**
2325 * security_fs_use - Determine how to handle labeling for a filesystem. 2328 * security_fs_use - Determine how to handle labeling for a filesystem.
2326 * @fstype: filesystem type 2329 * @sb: superblock in question
2327 * @behavior: labeling behavior
2328 * @sid: SID for filesystem (superblock)
2329 */ 2330 */
2330int security_fs_use( 2331int security_fs_use(struct super_block *sb)
2331 const char *fstype,
2332 unsigned int *behavior,
2333 u32 *sid)
2334{ 2332{
2335 int rc = 0; 2333 int rc = 0;
2336 struct ocontext *c; 2334 struct ocontext *c;
2335 struct superblock_security_struct *sbsec = sb->s_security;
2336 const char *fstype = sb->s_type->name;
2337 const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
2338 struct ocontext *base = NULL;
2337 2339
2338 read_lock(&policy_rwlock); 2340 read_lock(&policy_rwlock);
2339 2341
2340 c = policydb.ocontexts[OCON_FSUSE]; 2342 for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
2341 while (c) { 2343 char *sub;
2342 if (strcmp(fstype, c->u.name) == 0) 2344 int baselen;
2345
2346 baselen = strlen(fstype);
2347
2348 /* if base does not match, this is not the one */
2349 if (strncmp(fstype, c->u.name, baselen))
2350 continue;
2351
2352 /* if there is no subtype, this is the one! */
2353 if (!subtype)
2354 break;
2355
2356 /* skip past the base in this entry */
2357 sub = c->u.name + baselen;
2358
2359 /* entry is only a base. save it. keep looking for subtype */
2360 if (sub[0] == '\0') {
2361 base = c;
2362 continue;
2363 }
2364
2365 /* entry is not followed by a subtype, so it is not a match */
2366 if (sub[0] != '.')
2367 continue;
2368
2369 /* whew, we found a subtype of this fstype */
2370 sub++; /* move past '.' */
2371
2372 /* exact match of fstype AND subtype */
2373 if (!strcmp(subtype, sub))
2343 break; 2374 break;
2344 c = c->next;
2345 } 2375 }
2346 2376
2377 /* in case we had found an fstype match but no subtype match */
2378 if (!c)
2379 c = base;
2380
2347 if (c) { 2381 if (c) {
2348 *behavior = c->v.behavior; 2382 sbsec->behavior = c->v.behavior;
2349 if (!c->sid[0]) { 2383 if (!c->sid[0]) {
2350 rc = sidtab_context_to_sid(&sidtab, &c->context[0], 2384 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2351 &c->sid[0]); 2385 &c->sid[0]);
2352 if (rc) 2386 if (rc)
2353 goto out; 2387 goto out;
2354 } 2388 }
2355 *sid = c->sid[0]; 2389 sbsec->sid = c->sid[0];
2356 } else { 2390 } else {
2357 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 2391 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
2358 if (rc) { 2392 if (rc) {
2359 *behavior = SECURITY_FS_USE_NONE; 2393 sbsec->behavior = SECURITY_FS_USE_NONE;
2360 rc = 0; 2394 rc = 0;
2361 } else { 2395 } else {
2362 *behavior = SECURITY_FS_USE_GENFS; 2396 sbsec->behavior = SECURITY_FS_USE_GENFS;
2363 } 2397 }
2364 } 2398 }
2365 2399
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index d03081886214..a91d205ec0c6 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -56,7 +56,7 @@
56atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0); 56atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0);
57 57
58/* 58/*
59 * Returns true if an LSM/SELinux context 59 * Returns true if the context is an LSM/SELinux context.
60 */ 60 */
61static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx) 61static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
62{ 62{
@@ -66,7 +66,7 @@ static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
66} 66}
67 67
68/* 68/*
69 * Returns true if the xfrm contains a security blob for SELinux 69 * Returns true if the xfrm contains a security blob for SELinux.
70 */ 70 */
71static inline int selinux_authorizable_xfrm(struct xfrm_state *x) 71static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
72{ 72{
@@ -74,48 +74,111 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
74} 74}
75 75
76/* 76/*
77 * LSM hook implementation that authorizes that a flow can use 77 * Allocates a xfrm_sec_state and populates it using the supplied security
78 * a xfrm policy rule. 78 * xfrm_user_sec_ctx context.
79 */ 79 */
80int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) 80static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
81 struct xfrm_user_sec_ctx *uctx)
81{ 82{
82 int rc; 83 int rc;
83 u32 sel_sid; 84 const struct task_security_struct *tsec = current_security();
85 struct xfrm_sec_ctx *ctx = NULL;
86 u32 str_len;
84 87
85 /* Context sid is either set to label or ANY_ASSOC */ 88 if (ctxp == NULL || uctx == NULL ||
86 if (ctx) { 89 uctx->ctx_doi != XFRM_SC_DOI_LSM ||
87 if (!selinux_authorizable_ctx(ctx)) 90 uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
88 return -EINVAL; 91 return -EINVAL;
89
90 sel_sid = ctx->ctx_sid;
91 } else
92 /*
93 * All flows should be treated as polmatch'ing an
94 * otherwise applicable "non-labeled" policy. This
95 * would prevent inadvertent "leaks".
96 */
97 return 0;
98 92
99 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, 93 str_len = uctx->ctx_len;
100 ASSOCIATION__POLMATCH, 94 if (str_len >= PAGE_SIZE)
101 NULL); 95 return -ENOMEM;
102 96
103 if (rc == -EACCES) 97 ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL);
104 return -ESRCH; 98 if (!ctx)
99 return -ENOMEM;
105 100
101 ctx->ctx_doi = XFRM_SC_DOI_LSM;
102 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
103 ctx->ctx_len = str_len;
104 memcpy(ctx->ctx_str, &uctx[1], str_len);
105 ctx->ctx_str[str_len] = '\0';
106 rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid);
107 if (rc)
108 goto err;
109
110 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
111 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
112 if (rc)
113 goto err;
114
115 *ctxp = ctx;
116 atomic_inc(&selinux_xfrm_refcount);
117 return 0;
118
119err:
120 kfree(ctx);
106 return rc; 121 return rc;
107} 122}
108 123
109/* 124/*
125 * Free the xfrm_sec_ctx structure.
126 */
127static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
128{
129 if (!ctx)
130 return;
131
132 atomic_dec(&selinux_xfrm_refcount);
133 kfree(ctx);
134}
135
136/*
137 * Authorize the deletion of a labeled SA or policy rule.
138 */
139static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
140{
141 const struct task_security_struct *tsec = current_security();
142
143 if (!ctx)
144 return 0;
145
146 return avc_has_perm(tsec->sid, ctx->ctx_sid,
147 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
148 NULL);
149}
150
151/*
152 * LSM hook implementation that authorizes that a flow can use a xfrm policy
153 * rule.
154 */
155int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
156{
157 int rc;
158
159 /* All flows should be treated as polmatch'ing an otherwise applicable
160 * "non-labeled" policy. This would prevent inadvertent "leaks". */
161 if (!ctx)
162 return 0;
163
164 /* Context sid is either set to label or ANY_ASSOC */
165 if (!selinux_authorizable_ctx(ctx))
166 return -EINVAL;
167
168 rc = avc_has_perm(fl_secid, ctx->ctx_sid,
169 SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
170 return (rc == -EACCES ? -ESRCH : rc);
171}
172
173/*
110 * LSM hook implementation that authorizes that a state matches 174 * LSM hook implementation that authorizes that a state matches
111 * the given policy, flow combo. 175 * the given policy, flow combo.
112 */ 176 */
113 177int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
114int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, 178 struct xfrm_policy *xp,
115 const struct flowi *fl) 179 const struct flowi *fl)
116{ 180{
117 u32 state_sid; 181 u32 state_sid;
118 int rc;
119 182
120 if (!xp->security) 183 if (!xp->security)
121 if (x->security) 184 if (x->security)
@@ -138,187 +201,80 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
138 if (fl->flowi_secid != state_sid) 201 if (fl->flowi_secid != state_sid)
139 return 0; 202 return 0;
140 203
141 rc = avc_has_perm(fl->flowi_secid, state_sid, SECCLASS_ASSOCIATION, 204 /* We don't need a separate SA Vs. policy polmatch check since the SA
142 ASSOCIATION__SENDTO, 205 * is now of the same label as the flow and a flow Vs. policy polmatch
143 NULL)? 0:1; 206 * check had already happened in selinux_xfrm_policy_lookup() above. */
144 207 return (avc_has_perm(fl->flowi_secid, state_sid,
145 /* 208 SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
146 * We don't need a separate SA Vs. policy polmatch check 209 NULL) ? 0 : 1);
147 * since the SA is now of the same label as the flow and
148 * a flow Vs. policy polmatch check had already happened
149 * in selinux_xfrm_policy_lookup() above.
150 */
151
152 return rc;
153} 210}
154 211
155/* 212/*
156 * LSM hook implementation that checks and/or returns the xfrm sid for the 213 * LSM hook implementation that checks and/or returns the xfrm sid for the
157 * incoming packet. 214 * incoming packet.
158 */ 215 */
159
160int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) 216int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
161{ 217{
218 u32 sid_session = SECSID_NULL;
162 struct sec_path *sp; 219 struct sec_path *sp;
163 220
164 *sid = SECSID_NULL;
165
166 if (skb == NULL) 221 if (skb == NULL)
167 return 0; 222 goto out;
168 223
169 sp = skb->sp; 224 sp = skb->sp;
170 if (sp) { 225 if (sp) {
171 int i, sid_set = 0; 226 int i;
172 227
173 for (i = sp->len-1; i >= 0; i--) { 228 for (i = sp->len - 1; i >= 0; i--) {
174 struct xfrm_state *x = sp->xvec[i]; 229 struct xfrm_state *x = sp->xvec[i];
175 if (selinux_authorizable_xfrm(x)) { 230 if (selinux_authorizable_xfrm(x)) {
176 struct xfrm_sec_ctx *ctx = x->security; 231 struct xfrm_sec_ctx *ctx = x->security;
177 232
178 if (!sid_set) { 233 if (sid_session == SECSID_NULL) {
179 *sid = ctx->ctx_sid; 234 sid_session = ctx->ctx_sid;
180 sid_set = 1;
181
182 if (!ckall) 235 if (!ckall)
183 break; 236 goto out;
184 } else if (*sid != ctx->ctx_sid) 237 } else if (sid_session != ctx->ctx_sid) {
238 *sid = SECSID_NULL;
185 return -EINVAL; 239 return -EINVAL;
240 }
186 } 241 }
187 } 242 }
188 } 243 }
189 244
190 return 0;
191}
192
193/*
194 * Security blob allocation for xfrm_policy and xfrm_state
195 * CTX does not have a meaningful value on input
196 */
197static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
198 struct xfrm_user_sec_ctx *uctx, u32 sid)
199{
200 int rc = 0;
201 const struct task_security_struct *tsec = current_security();
202 struct xfrm_sec_ctx *ctx = NULL;
203 char *ctx_str = NULL;
204 u32 str_len;
205
206 BUG_ON(uctx && sid);
207
208 if (!uctx)
209 goto not_from_user;
210
211 if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
212 return -EINVAL;
213
214 str_len = uctx->ctx_len;
215 if (str_len >= PAGE_SIZE)
216 return -ENOMEM;
217
218 *ctxp = ctx = kmalloc(sizeof(*ctx) +
219 str_len + 1,
220 GFP_KERNEL);
221
222 if (!ctx)
223 return -ENOMEM;
224
225 ctx->ctx_doi = uctx->ctx_doi;
226 ctx->ctx_len = str_len;
227 ctx->ctx_alg = uctx->ctx_alg;
228
229 memcpy(ctx->ctx_str,
230 uctx+1,
231 str_len);
232 ctx->ctx_str[str_len] = 0;
233 rc = security_context_to_sid(ctx->ctx_str,
234 str_len,
235 &ctx->ctx_sid);
236
237 if (rc)
238 goto out;
239
240 /*
241 * Does the subject have permission to set security context?
242 */
243 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
244 SECCLASS_ASSOCIATION,
245 ASSOCIATION__SETCONTEXT, NULL);
246 if (rc)
247 goto out;
248
249 return rc;
250
251not_from_user:
252 rc = security_sid_to_context(sid, &ctx_str, &str_len);
253 if (rc)
254 goto out;
255
256 *ctxp = ctx = kmalloc(sizeof(*ctx) +
257 str_len,
258 GFP_ATOMIC);
259
260 if (!ctx) {
261 rc = -ENOMEM;
262 goto out;
263 }
264
265 ctx->ctx_doi = XFRM_SC_DOI_LSM;
266 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
267 ctx->ctx_sid = sid;
268 ctx->ctx_len = str_len;
269 memcpy(ctx->ctx_str,
270 ctx_str,
271 str_len);
272
273 goto out2;
274
275out: 245out:
276 *ctxp = NULL; 246 *sid = sid_session;
277 kfree(ctx); 247 return 0;
278out2:
279 kfree(ctx_str);
280 return rc;
281} 248}
282 249
283/* 250/*
284 * LSM hook implementation that allocs and transfers uctx spec to 251 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
285 * xfrm_policy.
286 */ 252 */
287int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 253int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
288 struct xfrm_user_sec_ctx *uctx) 254 struct xfrm_user_sec_ctx *uctx)
289{ 255{
290 int err; 256 return selinux_xfrm_alloc_user(ctxp, uctx);
291
292 BUG_ON(!uctx);
293
294 err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
295 if (err == 0)
296 atomic_inc(&selinux_xfrm_refcount);
297
298 return err;
299} 257}
300 258
301
302/* 259/*
303 * LSM hook implementation that copies security data structure from old to 260 * LSM hook implementation that copies security data structure from old to new
304 * new for policy cloning. 261 * for policy cloning.
305 */ 262 */
306int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 263int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
307 struct xfrm_sec_ctx **new_ctxp) 264 struct xfrm_sec_ctx **new_ctxp)
308{ 265{
309 struct xfrm_sec_ctx *new_ctx; 266 struct xfrm_sec_ctx *new_ctx;
310 267
311 if (old_ctx) { 268 if (!old_ctx)
312 new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, 269 return 0;
313 GFP_ATOMIC); 270
314 if (!new_ctx) 271 new_ctx = kmemdup(old_ctx, sizeof(*old_ctx) + old_ctx->ctx_len,
315 return -ENOMEM; 272 GFP_ATOMIC);
273 if (!new_ctx)
274 return -ENOMEM;
275 atomic_inc(&selinux_xfrm_refcount);
276 *new_ctxp = new_ctx;
316 277
317 memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
318 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
319 atomic_inc(&selinux_xfrm_refcount);
320 *new_ctxp = new_ctx;
321 }
322 return 0; 278 return 0;
323} 279}
324 280
@@ -327,8 +283,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
327 */ 283 */
328void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) 284void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
329{ 285{
330 atomic_dec(&selinux_xfrm_refcount); 286 selinux_xfrm_free(ctx);
331 kfree(ctx);
332} 287}
333 288
334/* 289/*
@@ -336,31 +291,55 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
336 */ 291 */
337int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) 292int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
338{ 293{
339 const struct task_security_struct *tsec = current_security(); 294 return selinux_xfrm_delete(ctx);
340 295}
341 if (!ctx)
342 return 0;
343 296
344 return avc_has_perm(tsec->sid, ctx->ctx_sid, 297/*
345 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, 298 * LSM hook implementation that allocates a xfrm_sec_state, populates it using
346 NULL); 299 * the supplied security context, and assigns it to the xfrm_state.
300 */
301int selinux_xfrm_state_alloc(struct xfrm_state *x,
302 struct xfrm_user_sec_ctx *uctx)
303{
304 return selinux_xfrm_alloc_user(&x->security, uctx);
347} 305}
348 306
349/* 307/*
350 * LSM hook implementation that allocs and transfers sec_ctx spec to 308 * LSM hook implementation that allocates a xfrm_sec_state and populates based
351 * xfrm_state. 309 * on a secid.
352 */ 310 */
353int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx, 311int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
354 u32 secid) 312 struct xfrm_sec_ctx *polsec, u32 secid)
355{ 313{
356 int err; 314 int rc;
315 struct xfrm_sec_ctx *ctx;
316 char *ctx_str = NULL;
317 int str_len;
318
319 if (!polsec)
320 return 0;
357 321
358 BUG_ON(!x); 322 if (secid == 0)
323 return -EINVAL;
359 324
360 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid); 325 rc = security_sid_to_context(secid, &ctx_str, &str_len);
361 if (err == 0) 326 if (rc)
362 atomic_inc(&selinux_xfrm_refcount); 327 return rc;
363 return err; 328
329 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
330 if (!ctx)
331 return -ENOMEM;
332
333 ctx->ctx_doi = XFRM_SC_DOI_LSM;
334 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
335 ctx->ctx_sid = secid;
336 ctx->ctx_len = str_len;
337 memcpy(ctx->ctx_str, ctx_str, str_len);
338 kfree(ctx_str);
339
340 x->security = ctx;
341 atomic_inc(&selinux_xfrm_refcount);
342 return 0;
364} 343}
365 344
366/* 345/*
@@ -368,24 +347,15 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
368 */ 347 */
369void selinux_xfrm_state_free(struct xfrm_state *x) 348void selinux_xfrm_state_free(struct xfrm_state *x)
370{ 349{
371 atomic_dec(&selinux_xfrm_refcount); 350 selinux_xfrm_free(x->security);
372 kfree(x->security);
373} 351}
374 352
375 /* 353/*
376 * LSM hook implementation that authorizes deletion of labeled SAs. 354 * LSM hook implementation that authorizes deletion of labeled SAs.
377 */ 355 */
378int selinux_xfrm_state_delete(struct xfrm_state *x) 356int selinux_xfrm_state_delete(struct xfrm_state *x)
379{ 357{
380 const struct task_security_struct *tsec = current_security(); 358 return selinux_xfrm_delete(x->security);
381 struct xfrm_sec_ctx *ctx = x->security;
382
383 if (!ctx)
384 return 0;
385
386 return avc_has_perm(tsec->sid, ctx->ctx_sid,
387 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
388 NULL);
389} 359}
390 360
391/* 361/*
@@ -395,14 +365,12 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
395 * we need to check for unlabelled access since this may not have 365 * we need to check for unlabelled access since this may not have
396 * gone thru the IPSec process. 366 * gone thru the IPSec process.
397 */ 367 */
398int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, 368int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
399 struct common_audit_data *ad) 369 struct common_audit_data *ad)
400{ 370{
401 int i, rc = 0; 371 int i;
402 struct sec_path *sp; 372 struct sec_path *sp = skb->sp;
403 u32 sel_sid = SECINITSID_UNLABELED; 373 u32 peer_sid = SECINITSID_UNLABELED;
404
405 sp = skb->sp;
406 374
407 if (sp) { 375 if (sp) {
408 for (i = 0; i < sp->len; i++) { 376 for (i = 0; i < sp->len; i++) {
@@ -410,23 +378,17 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
410 378
411 if (x && selinux_authorizable_xfrm(x)) { 379 if (x && selinux_authorizable_xfrm(x)) {
412 struct xfrm_sec_ctx *ctx = x->security; 380 struct xfrm_sec_ctx *ctx = x->security;
413 sel_sid = ctx->ctx_sid; 381 peer_sid = ctx->ctx_sid;
414 break; 382 break;
415 } 383 }
416 } 384 }
417 } 385 }
418 386
419 /* 387 /* This check even when there's no association involved is intended,
420 * This check even when there's no association involved is 388 * according to Trent Jaeger, to make sure a process can't engage in
421 * intended, according to Trent Jaeger, to make sure a 389 * non-IPsec communication unless explicitly allowed by policy. */
422 * process can't engage in non-ipsec communication unless 390 return avc_has_perm(sk_sid, peer_sid,
423 * explicitly allowed by policy. 391 SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
424 */
425
426 rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
427 ASSOCIATION__RECVFROM, ad);
428
429 return rc;
430} 392}
431 393
432/* 394/*
@@ -436,49 +398,38 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
436 * If we do have a authorizable security association, then it has already been 398 * If we do have a authorizable security association, then it has already been
437 * checked in the selinux_xfrm_state_pol_flow_match hook above. 399 * checked in the selinux_xfrm_state_pol_flow_match hook above.
438 */ 400 */
439int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 401int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
440 struct common_audit_data *ad, u8 proto) 402 struct common_audit_data *ad, u8 proto)
441{ 403{
442 struct dst_entry *dst; 404 struct dst_entry *dst;
443 int rc = 0;
444
445 dst = skb_dst(skb);
446
447 if (dst) {
448 struct dst_entry *dst_test;
449
450 for (dst_test = dst; dst_test != NULL;
451 dst_test = dst_test->child) {
452 struct xfrm_state *x = dst_test->xfrm;
453
454 if (x && selinux_authorizable_xfrm(x))
455 goto out;
456 }
457 }
458 405
459 switch (proto) { 406 switch (proto) {
460 case IPPROTO_AH: 407 case IPPROTO_AH:
461 case IPPROTO_ESP: 408 case IPPROTO_ESP:
462 case IPPROTO_COMP: 409 case IPPROTO_COMP:
463 /* 410 /* We should have already seen this packet once before it
464 * We should have already seen this packet once before 411 * underwent xfrm(s). No need to subject it to the unlabeled
465 * it underwent xfrm(s). No need to subject it to the 412 * check. */
466 * unlabeled check. 413 return 0;
467 */
468 goto out;
469 default: 414 default:
470 break; 415 break;
471 } 416 }
472 417
473 /* 418 dst = skb_dst(skb);
474 * This check even when there's no association involved is 419 if (dst) {
475 * intended, according to Trent Jaeger, to make sure a 420 struct dst_entry *iter;
476 * process can't engage in non-ipsec communication unless
477 * explicitly allowed by policy.
478 */
479 421
480 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 422 for (iter = dst; iter != NULL; iter = iter->child) {
481 ASSOCIATION__SENDTO, ad); 423 struct xfrm_state *x = iter->xfrm;
482out: 424
483 return rc; 425 if (x && selinux_authorizable_xfrm(x))
426 return 0;
427 }
428 }
429
430 /* This check even when there's no association involved is intended,
431 * according to Trent Jaeger, to make sure a process can't engage in
432 * non-IPsec communication unless explicitly allowed by policy. */
433 return avc_has_perm(sk_sid, SECINITSID_UNLABELED,
434 SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
484} 435}