Merge branch 'master' of git://git.infradead.org/users/pcmoore/selinux into ra-next
authorJames Morris <james.l.morris@oracle.com>
Tue, 22 Oct 2013 11:26:41 +0000 (22:26 +1100)
committerJames Morris <james.l.morris@oracle.com>
Tue, 22 Oct 2013 11:26:41 +0000 (22:26 +1100)
1  2 
include/linux/security.h
security/capability.c
security/security.c
security/selinux/hooks.c
security/selinux/include/xfrm.h

diff --combined include/linux/security.h
index 9d37e2b9d3ec030f026117d99de94dfd50b32ab0,8d23951a3805668959542ce02a339dca41c207cd..5623a7f965b7bbb07ab94a72351aec027ef4adb7
@@@ -1052,17 -1052,25 +1052,25 @@@ static inline void security_free_mnt_op
   * @xfrm_policy_delete_security:
   *    @ctx contains the xfrm_sec_ctx.
   *    Authorize deletion of xp->security.
-  * @xfrm_state_alloc_security:
+  * @xfrm_state_alloc:
   *    @x contains the xfrm_state being added to the Security Association
   *    Database by the XFRM system.
   *    @sec_ctx contains the security context information being provided by
   *    the user-level SA generation program (e.g., setkey or racoon).
-  *    @secid contains the secid from which to take the mls portion of the context.
   *    Allocate a security structure to the x->security field; the security
   *    field is initialized to NULL when the xfrm_state is allocated. Set the
-  *    context to correspond to either sec_ctx or polsec, with the mls portion
-  *    taken from secid in the latter case.
-  *    Return 0 if operation was successful (memory to allocate, legal context).
+  *    context to correspond to sec_ctx. Return 0 if operation was successful
+  *    (memory to allocate, legal context).
+  * @xfrm_state_alloc_acquire:
+  *    @x contains the xfrm_state being added to the Security Association
+  *    Database by the XFRM system.
+  *    @polsec contains the policy's security context.
+  *    @secid contains the secid from which to take the mls portion of the
+  *    context.
+  *    Allocate a security structure to the x->security field; the security
+  *    field is initialized to NULL when the xfrm_state is allocated. Set the
+  *    context to correspond to secid. Return 0 if operation was successful
+  *    (memory to allocate, legal context).
   * @xfrm_state_free_security:
   *    @x contains the xfrm_state.
   *    Deallocate x->security.
@@@ -1492,7 -1500,7 +1500,7 @@@ struct security_operations 
        int (*inode_alloc_security) (struct inode *inode);
        void (*inode_free_security) (struct inode *inode);
        int (*inode_init_security) (struct inode *inode, struct inode *dir,
 -                                  const struct qstr *qstr, char **name,
 +                                  const struct qstr *qstr, const char **name,
                                    void **value, size_t *len);
        int (*inode_create) (struct inode *dir,
                             struct dentry *dentry, umode_t mode);
        int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx);
        void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx);
        int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx);
-       int (*xfrm_state_alloc_security) (struct xfrm_state *x,
-               struct xfrm_user_sec_ctx *sec_ctx,
-               u32 secid);
+       int (*xfrm_state_alloc) (struct xfrm_state *x,
+                                struct xfrm_user_sec_ctx *sec_ctx);
+       int (*xfrm_state_alloc_acquire) (struct xfrm_state *x,
+                                        struct xfrm_sec_ctx *polsec,
+                                        u32 secid);
        void (*xfrm_state_free_security) (struct xfrm_state *x);
        int (*xfrm_state_delete_security) (struct xfrm_state *x);
        int (*xfrm_policy_lookup) (struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
@@@ -1770,7 -1780,7 +1780,7 @@@ int security_inode_init_security(struc
                                 const struct qstr *qstr,
                                 initxattrs initxattrs, void *fs_data);
  int security_old_inode_init_security(struct inode *inode, struct inode *dir,
 -                                   const struct qstr *qstr, char **name,
 +                                   const struct qstr *qstr, const char **name,
                                     void **value, size_t *len);
  int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode);
  int security_inode_link(struct dentry *old_dentry, struct inode *dir,
@@@ -2094,8 -2104,8 +2104,8 @@@ static inline int security_inode_init_s
  static inline int security_old_inode_init_security(struct inode *inode,
                                                   struct inode *dir,
                                                   const struct qstr *qstr,
 -                                                 char **name, void **value,
 -                                                 size_t *len)
 +                                                 const char **name,
 +                                                 void **value, size_t *len)
  {
        return -EOPNOTSUPP;
  }
diff --combined security/capability.c
index dbeb9bc27b24a14b7f546a44843bba2757db77cb,b6d779b6aa25864e99557a77bbe2f06856d1f5ea..8b4f24ae43381de05af67271edd9a8ddd57c651f
@@@ -129,7 -129,7 +129,7 @@@ static void cap_inode_free_security(str
  }
  
  static int cap_inode_init_security(struct inode *inode, struct inode *dir,
 -                                 const struct qstr *qstr, char **name,
 +                                 const struct qstr *qstr, const char **name,
                                   void **value, size_t *len)
  {
        return -EOPNOTSUPP;
@@@ -777,9 -777,15 +777,15 @@@ static int cap_xfrm_policy_delete_secur
        return 0;
  }
  
- static int cap_xfrm_state_alloc_security(struct xfrm_state *x,
-                                        struct xfrm_user_sec_ctx *sec_ctx,
-                                        u32 secid)
+ static int cap_xfrm_state_alloc(struct xfrm_state *x,
+                               struct xfrm_user_sec_ctx *sec_ctx)
+ {
+       return 0;
+ }
+ static int cap_xfrm_state_alloc_acquire(struct xfrm_state *x,
+                                       struct xfrm_sec_ctx *polsec,
+                                       u32 secid)
  {
        return 0;
  }
@@@ -1101,7 -1107,8 +1107,8 @@@ void __init security_fixup_ops(struct s
        set_to_cap_if_null(ops, xfrm_policy_clone_security);
        set_to_cap_if_null(ops, xfrm_policy_free_security);
        set_to_cap_if_null(ops, xfrm_policy_delete_security);
-       set_to_cap_if_null(ops, xfrm_state_alloc_security);
+       set_to_cap_if_null(ops, xfrm_state_alloc);
+       set_to_cap_if_null(ops, xfrm_state_alloc_acquire);
        set_to_cap_if_null(ops, xfrm_state_free_security);
        set_to_cap_if_null(ops, xfrm_state_delete_security);
        set_to_cap_if_null(ops, xfrm_policy_lookup);
diff --combined security/security.c
index 4dc31f4f2700626cb951aed5e874f0ce18d8b064,94048028bdd113cee690a755b468666e608979b7..15b6928592ef68aac565e3fc94daf4737b6adc54
@@@ -348,10 -348,10 +348,10 @@@ int security_inode_init_security(struc
        if (unlikely(IS_PRIVATE(inode)))
                return 0;
  
 -      memset(new_xattrs, 0, sizeof new_xattrs);
        if (!initxattrs)
                return security_ops->inode_init_security(inode, dir, qstr,
                                                         NULL, NULL, NULL);
 +      memset(new_xattrs, 0, sizeof(new_xattrs));
        lsm_xattr = new_xattrs;
        ret = security_ops->inode_init_security(inode, dir, qstr,
                                                &lsm_xattr->name,
                goto out;
        ret = initxattrs(inode, new_xattrs, fs_data);
  out:
 -      for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
 -              kfree(xattr->name);
 +      for (xattr = new_xattrs; xattr->value != NULL; xattr++)
                kfree(xattr->value);
 -      }
        return (ret == -EOPNOTSUPP) ? 0 : ret;
  }
  EXPORT_SYMBOL(security_inode_init_security);
  
  int security_old_inode_init_security(struct inode *inode, struct inode *dir,
 -                                   const struct qstr *qstr, char **name,
 +                                   const struct qstr *qstr, const char **name,
                                     void **value, size_t *len)
  {
        if (unlikely(IS_PRIVATE(inode)))
@@@ -1340,22 -1342,17 +1340,17 @@@ int security_xfrm_policy_delete(struct 
        return security_ops->xfrm_policy_delete_security(ctx);
  }
  
- int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+ int security_xfrm_state_alloc(struct xfrm_state *x,
+                             struct xfrm_user_sec_ctx *sec_ctx)
  {
-       return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0);
+       return security_ops->xfrm_state_alloc(x, sec_ctx);
  }
  EXPORT_SYMBOL(security_xfrm_state_alloc);
  
  int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
                                      struct xfrm_sec_ctx *polsec, u32 secid)
  {
-       if (!polsec)
-               return 0;
-       /*
-        * We want the context to be taken from secid which is usually
-        * from the sock.
-        */
-       return security_ops->xfrm_state_alloc_security(x, NULL, secid);
+       return security_ops->xfrm_state_alloc_acquire(x, polsec, secid);
  }
  
  int security_xfrm_state_delete(struct xfrm_state *x)
diff --combined security/selinux/hooks.c
index a5091ec06aa62816798510e40a1bcf005d2abd3d,c09211a4d7da2b88398d702b87defb1f3a1d2f00..6d0bf5c0c8323a4f0f56f1879fce1a6c4c53e8fa
@@@ -95,7 -95,9 +95,9 @@@
  #include "audit.h"
  #include "avc_ss.h"
  
- #define NUM_SEL_MNT_OPTS 5
+ #define SB_TYPE_FMT "%s%s%s"
+ #define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
+ #define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
  
  extern struct security_operations *security_ops;
  
@@@ -139,12 -141,28 +141,28 @@@ static struct kmem_cache *sel_inode_cac
   * This function checks the SECMARK reference counter to see if any SECMARK
   * targets are currently configured, if the reference counter is greater than
   * zero SECMARK is considered to be enabled.  Returns true (1) if SECMARK is
-  * enabled, false (0) if SECMARK is disabled.
+  * enabled, false (0) if SECMARK is disabled.  If the always_check_network
+  * policy capability is enabled, SECMARK is always considered enabled.
   *
   */
  static int selinux_secmark_enabled(void)
  {
-       return (atomic_read(&selinux_secmark_refcount) > 0);
+       return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
+ }
+ /**
+  * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
+  *
+  * Description:
+  * This function checks if NetLabel or labeled IPSEC is enabled.  Returns true
+  * (1) if any are enabled or false (0) if neither are enabled.  If the
+  * always_check_network policy capability is enabled, peer labeling
+  * is always considered enabled.
+  *
+  */
+ static int selinux_peerlbl_enabled(void)
+ {
+       return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
  }
  
  /*
@@@ -309,8 -327,11 +327,11 @@@ enum 
        Opt_defcontext = 3,
        Opt_rootcontext = 4,
        Opt_labelsupport = 5,
+       Opt_nextmntopt = 6,
  };
  
+ #define NUM_SEL_MNT_OPTS      (Opt_nextmntopt - 1)
  static const match_table_t tokens = {
        {Opt_context, CONTEXT_STR "%s"},
        {Opt_fscontext, FSCONTEXT_STR "%s"},
@@@ -355,6 -376,29 +376,29 @@@ static int may_context_mount_inode_rela
        return rc;
  }
  
+ static int selinux_is_sblabel_mnt(struct super_block *sb)
+ {
+       struct superblock_security_struct *sbsec = sb->s_security;
+       if (sbsec->behavior == SECURITY_FS_USE_XATTR ||
+           sbsec->behavior == SECURITY_FS_USE_TRANS ||
+           sbsec->behavior == SECURITY_FS_USE_TASK)
+               return 1;
+       /* Special handling for sysfs. Is genfs but also has setxattr handler*/
+       if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
+               return 1;
+       /*
+        * Special handling for rootfs. Is genfs but supports
+        * setting SELinux context on in-core inodes.
+        */
+       if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
+               return 1;
+       return 0;
+ }
  static int sb_finish_set_opts(struct super_block *sb)
  {
        struct superblock_security_struct *sbsec = sb->s_security;
                   the first boot of the SELinux kernel before we have
                   assigned xattr values to the filesystem. */
                if (!root_inode->i_op->getxattr) {
-                       printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
-                              "xattr support\n", sb->s_id, sb->s_type->name);
+                       printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
+                              "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
                        rc = -EOPNOTSUPP;
                        goto out;
                }
                if (rc < 0 && rc != -ENODATA) {
                        if (rc == -EOPNOTSUPP)
                                printk(KERN_WARNING "SELinux: (dev %s, type "
-                                      "%s) has no security xattr handler\n",
-                                      sb->s_id, sb->s_type->name);
+                                      SB_TYPE_FMT") has no security xattr handler\n",
+                                      sb->s_id, SB_TYPE_ARGS(sb));
                        else
                                printk(KERN_WARNING "SELinux: (dev %s, type "
-                                      "%s) getxattr errno %d\n", sb->s_id,
-                                      sb->s_type->name, -rc);
+                                      SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
+                                      SB_TYPE_ARGS(sb), -rc);
                        goto out;
                }
        }
  
-       sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
        if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
-               printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
-                      sb->s_id, sb->s_type->name);
+               printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
+                      sb->s_id, SB_TYPE_ARGS(sb));
        else
-               printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
-                      sb->s_id, sb->s_type->name,
+               printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
+                      sb->s_id, SB_TYPE_ARGS(sb),
                       labeling_behaviors[sbsec->behavior-1]);
  
-       if (sbsec->behavior == SECURITY_FS_USE_GENFS ||
-           sbsec->behavior == SECURITY_FS_USE_MNTPOINT ||
-           sbsec->behavior == SECURITY_FS_USE_NONE ||
-           sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
-               sbsec->flags &= ~SE_SBLABELSUPP;
-       /* Special handling for sysfs. Is genfs but also has setxattr handler*/
-       if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
-               sbsec->flags |= SE_SBLABELSUPP;
+       sbsec->flags |= SE_SBINITIALIZED;
+       if (selinux_is_sblabel_mnt(sb))
+               sbsec->flags |= SBLABEL_MNT;
  
        /* Initialize the root inode. */
        rc = inode_doinit_with_dentry(root_inode, root);
@@@ -460,15 -496,18 +496,18 @@@ static int selinux_get_mnt_opts(const s
        if (!ss_initialized)
                return -EINVAL;
  
+       /* make sure we always check enough bits to cover the mask */
+       BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
        tmp = sbsec->flags & SE_MNTMASK;
        /* count the number of mount options for this sb */
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
                if (tmp & 0x01)
                        opts->num_mnt_opts++;
                tmp >>= 1;
        }
        /* Check if the Label support flag is set */
-       if (sbsec->flags & SE_SBLABELSUPP)
+       if (sbsec->flags & SBLABEL_MNT)
                opts->num_mnt_opts++;
  
        opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
                opts->mnt_opts[i] = context;
                opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
        }
-       if (sbsec->flags & SE_SBLABELSUPP) {
+       if (sbsec->flags & SBLABEL_MNT) {
                opts->mnt_opts[i] = NULL;
-               opts->mnt_opts_flags[i++] = SE_SBLABELSUPP;
+               opts->mnt_opts_flags[i++] = SBLABEL_MNT;
        }
  
        BUG_ON(i != opts->num_mnt_opts);
@@@ -561,7 -600,6 +600,6 @@@ static int selinux_set_mnt_opts(struct 
        const struct cred *cred = current_cred();
        int rc = 0, i;
        struct superblock_security_struct *sbsec = sb->s_security;
-       const char *name = sb->s_type->name;
        struct inode *inode = sbsec->sb->s_root->d_inode;
        struct inode_security_struct *root_isec = inode->i_security;
        u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
        for (i = 0; i < num_opts; i++) {
                u32 sid;
  
-               if (flags[i] == SE_SBLABELSUPP)
+               if (flags[i] == SBLABEL_MNT)
                        continue;
                rc = security_context_to_sid(mount_options[i],
                                             strlen(mount_options[i]), &sid);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_to_sid"
-                              "(%s) failed for (dev %s, type %s) errno=%d\n",
-                              mount_options[i], sb->s_id, name, rc);
+                              "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
+                              mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
                        goto out;
                }
                switch (flags[i]) {
                 * Determine the labeling behavior to use for this
                 * filesystem type.
                 */
-               rc = security_fs_use((sbsec->flags & SE_SBPROC) ?
-                                       "proc" : sb->s_type->name,
-                                       &sbsec->behavior, &sbsec->sid);
+               rc = security_fs_use(sb);
                if (rc) {
                        printk(KERN_WARNING
                                "%s: security_fs_use(%s) returned %d\n",
@@@ -770,7 -806,8 +806,8 @@@ out
  out_double_mount:
        rc = -EINVAL;
        printk(KERN_WARNING "SELinux: mount invalid.  Same superblock, different "
-              "security settings for (dev %s, type %s)\n", sb->s_id, name);
+              "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
+              SB_TYPE_ARGS(sb));
        goto out;
  }
  
@@@ -1037,7 -1074,7 +1074,7 @@@ static void selinux_write_opts(struct s
                case DEFCONTEXT_MNT:
                        prefix = DEFCONTEXT_STR;
                        break;
-               case SE_SBLABELSUPP:
+               case SBLABEL_MNT:
                        seq_putc(m, ',');
                        seq_puts(m, LABELSUPP_STR);
                        continue;
@@@ -1650,7 -1687,7 +1687,7 @@@ static int may_create(struct inode *dir
        if (rc)
                return rc;
  
-       if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
+       if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
                rc = security_transition_sid(sid, dsec->sid, tclass,
                                             &dentry->d_name, &newsid);
                if (rc)
@@@ -2438,14 -2475,14 +2475,14 @@@ static int selinux_sb_remount(struct su
                u32 sid;
                size_t len;
  
-               if (flags[i] == SE_SBLABELSUPP)
+               if (flags[i] == SBLABEL_MNT)
                        continue;
                len = strlen(mount_options[i]);
                rc = security_context_to_sid(mount_options[i], len, &sid);
                if (rc) {
                        printk(KERN_WARNING "SELinux: security_context_to_sid"
-                              "(%s) failed for (dev %s, type %s) errno=%d\n",
-                              mount_options[i], sb->s_id, sb->s_type->name, rc);
+                              "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
+                              mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
                        goto out_free_opts;
                }
                rc = -EINVAL;
@@@ -2483,8 -2520,8 +2520,8 @@@ out_free_secdata
        return rc;
  out_bad_option:
        printk(KERN_WARNING "SELinux: unable to change security options "
-              "during remount (dev %s, type=%s)\n", sb->s_id,
-              sb->s_type->name);
+              "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
+              SB_TYPE_ARGS(sb));
        goto out_free_opts;
  }
  
@@@ -2587,8 -2624,7 +2624,8 @@@ static int selinux_dentry_init_security
  }
  
  static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 -                                     const struct qstr *qstr, char **name,
 +                                     const struct qstr *qstr,
 +                                     const char **name,
                                       void **value, size_t *len)
  {
        const struct task_security_struct *tsec = current_security();
        struct superblock_security_struct *sbsec;
        u32 sid, newsid, clen;
        int rc;
 -      char *namep = NULL, *context;
 +      char *context;
  
        dsec = dir->i_security;
        sbsec = dir->i_sb->s_security;
        if ((sbsec->flags & SE_SBINITIALIZED) &&
            (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
                newsid = sbsec->mntpoint_sid;
-       else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
+       else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
                rc = security_transition_sid(sid, dsec->sid,
                                             inode_mode_to_security_class(inode->i_mode),
                                             qstr, &newsid);
                isec->initialized = 1;
        }
  
-       if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP))
+       if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
  
 -      if (name) {
 -              namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_NOFS);
 -              if (!namep)
 -                      return -ENOMEM;
 -              *name = namep;
 -      }
 +      if (name)
 +              *name = XATTR_SELINUX_SUFFIX;
  
        if (value && len) {
                rc = security_sid_to_context_force(newsid, &context, &clen);
 -              if (rc) {
 -                      kfree(namep);
 +              if (rc)
                        return rc;
 -              }
                *value = context;
                *len = clen;
        }
@@@ -2831,7 -2873,7 +2868,7 @@@ static int selinux_inode_setxattr(struc
                return selinux_inode_setotherxattr(dentry, name);
  
        sbsec = inode->i_sb->s_security;
-       if (!(sbsec->flags & SE_SBLABELSUPP))
+       if (!(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
  
        if (!inode_owner_or_capable(inode))
@@@ -3792,8 -3834,12 +3829,12 @@@ static int selinux_skb_peerlbl_sid(stru
        u32 nlbl_sid;
        u32 nlbl_type;
  
-       selinux_skb_xfrm_sid(skb, &xfrm_sid);
-       selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
+       err = selinux_skb_xfrm_sid(skb, &xfrm_sid);
+       if (unlikely(err))
+               return -EACCES;
+       err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
+       if (unlikely(err))
+               return -EACCES;
  
        err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
        if (unlikely(err)) {
@@@ -4247,7 -4293,7 +4288,7 @@@ static int selinux_socket_sock_rcv_skb(
                return selinux_sock_rcv_skb_compat(sk, skb, family);
  
        secmark_active = selinux_secmark_enabled();
-       peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
+       peerlbl_active = selinux_peerlbl_enabled();
        if (!secmark_active && !peerlbl_active)
                return 0;
  
@@@ -4629,7 -4675,7 +4670,7 @@@ static unsigned int selinux_ip_forward(
  
        secmark_active = selinux_secmark_enabled();
        netlbl_active = netlbl_enabled();
-       peerlbl_active = netlbl_active || selinux_xfrm_enabled();
+       peerlbl_active = selinux_peerlbl_enabled();
        if (!secmark_active && !peerlbl_active)
                return NF_ACCEPT;
  
@@@ -4781,7 -4827,7 +4822,7 @@@ static unsigned int selinux_ip_postrout
                return NF_ACCEPT;
  #endif
        secmark_active = selinux_secmark_enabled();
-       peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
+       peerlbl_active = selinux_peerlbl_enabled();
        if (!secmark_active && !peerlbl_active)
                return NF_ACCEPT;
  
@@@ -5785,7 -5831,8 +5826,8 @@@ static struct security_operations selin
        .xfrm_policy_clone_security =   selinux_xfrm_policy_clone,
        .xfrm_policy_free_security =    selinux_xfrm_policy_free,
        .xfrm_policy_delete_security =  selinux_xfrm_policy_delete,
-       .xfrm_state_alloc_security =    selinux_xfrm_state_alloc,
+       .xfrm_state_alloc =             selinux_xfrm_state_alloc,
+       .xfrm_state_alloc_acquire =     selinux_xfrm_state_alloc_acquire,
        .xfrm_state_free_security =     selinux_xfrm_state_free,
        .xfrm_state_delete_security =   selinux_xfrm_state_delete,
        .xfrm_policy_lookup =           selinux_xfrm_policy_lookup,
index 6713f04e30ba8810415f88f7ed6e78cb5685f6f4,7605251936f502bef385bec737eb4b85c7c3df7f..0dec76c64cf53853d0eea6aac983db307c8636b8
  #include <net/flow.h>
  
  int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
-                             struct xfrm_user_sec_ctx *sec_ctx);
+                             struct xfrm_user_sec_ctx *uctx);
  int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
                              struct xfrm_sec_ctx **new_ctxp);
  void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
  int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
  int selinux_xfrm_state_alloc(struct xfrm_state *x,
-       struct xfrm_user_sec_ctx *sec_ctx, u32 secid);
+                            struct xfrm_user_sec_ctx *uctx);
+ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
+                                    struct xfrm_sec_ctx *polsec, u32 secid);
  void selinux_xfrm_state_free(struct xfrm_state *x);
  int selinux_xfrm_state_delete(struct xfrm_state *x);
  int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
  int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
-                       struct xfrm_policy *xp, const struct flowi *fl);
- /*
-  * Extract the security blob from the sock (it's actually on the socket)
-  */
- static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
- {
-       if (!sk->sk_socket)
-               return NULL;
-       return SOCK_INODE(sk->sk_socket)->i_security;
- }
+                                     struct xfrm_policy *xp,
+                                     const struct flowi *fl);
  
  #ifdef CONFIG_SECURITY_NETWORK_XFRM
  extern atomic_t selinux_xfrm_refcount;
@@@ -42,21 -34,16 +34,21 @@@ static inline int selinux_xfrm_enabled(
        return (atomic_read(&selinux_xfrm_refcount) > 0);
  }
  
- int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
-                       struct common_audit_data *ad);
- int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
-                       struct common_audit_data *ad, u8 proto);
+ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
+                             struct common_audit_data *ad);
+ int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
+                               struct common_audit_data *ad, u8 proto);
  int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
  
  static inline void selinux_xfrm_notify_policyload(void)
  {
 +      struct net *net;
 +
        atomic_inc(&flow_cache_genid);
 -      rt_genid_bump(&init_net);
 +      rtnl_lock();
 +      for_each_net(net)
 +              rt_genid_bump_all(net);
 +      rtnl_unlock();
  }
  #else
  static inline int selinux_xfrm_enabled(void)
        return 0;
  }
  
- static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
-                       struct common_audit_data *ad)
+ static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
+                                           struct common_audit_data *ad)
  {
        return 0;
  }
  
- static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
-                       struct common_audit_data *ad, u8 proto)
+ static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
+                                             struct common_audit_data *ad,
+                                             u8 proto)
  {
        return 0;
  }
  
- static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
+ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid,
+                                             int ckall)
  {
        *sid = SECSID_NULL;
        return 0;
@@@ -87,10 -76,9 +81,9 @@@ static inline void selinux_xfrm_notify_
  }
  #endif
  
- static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
+ static inline int selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
  {
-       int err = selinux_xfrm_decode_session(skb, sid, 0);
-       BUG_ON(err);
+       return selinux_xfrm_decode_session(skb, sid, 0);
  }
  
  #endif /* _SELINUX_XFRM_H_ */
This page took 0.038575 seconds and 5 git commands to generate.