]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Revert "UBUNTU: SAUCE: LSM stacking: LSM: Infrastructure management of the remaining...
authorJoseph Salisbury <joseph.salisbury@canonical.com>
Mon, 12 Mar 2018 19:07:00 +0000 (20:07 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Tue, 3 Apr 2018 09:40:24 +0000 (11:40 +0200)
BugLink: http://bugs.launchpad.net/bugs/1734327
This commit introduced a regression identified in bug 1734327.  The regression
causes a kernel panic to occur after multiple TCP connection creations/closures
to the localhost.  The bug was found using STAF RPC calls, but is easily reproducible with SSH.

The patch author for commit ac8f82a0b6d9 has been notificed of this revert.
For now stacking is just a technology preview, which is why we are reverting the patch.
There is a new revision of the stacking patches the jjohansen is working on,
and he will try to see if we can't get it resolved there.

This reverts commit ac8f82a0b6d91ca884de361ff68946ec95c64bc6.

Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
include/linux/lsm_hooks.h
security/security.c
security/selinux/hooks.c
security/selinux/include/objsec.h
security/selinux/netlabel.c
security/selinux/selinuxfs.c
security/selinux/ss/services.c
security/smack/smack.h
security/smack/smack_lsm.c
security/smack/smack_netfilter.c

index fbc95945d03729858e1e2fc8c75efaba6eac05ec..9893e3b4321d04cc23e6c6959185538a1c802943 100644 (file)
@@ -1945,12 +1945,6 @@ struct security_hook_list {
 struct lsm_blob_sizes {
        int     lbs_cred;
        int     lbs_file;
-       int     lbs_inode;
-       int     lbs_ipc;
-       int     lbs_key;
-       int     lbs_msg_msg;
-       int     lbs_sock;
-       int     lbs_superblock;
        int     lbs_task;
 };
 
@@ -2014,11 +2008,9 @@ static inline void loadpin_add_hooks(void) { };
 #endif
 
 extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp);
-extern int lsm_inode_alloc(struct inode *inode);
 
 #ifdef CONFIG_SECURITY
 void lsm_early_cred(struct cred *cred);
-void lsm_early_inode(struct inode *inode);
 #endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
index cdc1627e43ef0d7a52430c2644559383ac89ca10..95d6b85a951c30c55b08fbd70fd6d86a487709da 100644 (file)
 #include <linux/personality.h>
 #include <linux/backing-dev.h>
 #include <linux/string.h>
-#include <linux/msg.h>
 #include <linux/prctl.h>
 #include <net/flow.h>
-#include <net/sock.h>
 
 #define MAX_LSM_EVM_XATTR      2
 
@@ -117,16 +115,8 @@ int __init security_init(void)
 #ifdef CONFIG_SECURITY_LSM_DEBUG
        pr_info("LSM: cred blob size       = %d\n", blob_sizes.lbs_cred);
        pr_info("LSM: file blob size       = %d\n", blob_sizes.lbs_file);
-       pr_info("LSM: inode blob size      = %d\n", blob_sizes.lbs_inode);
-       pr_info("LSM: ipc blob size        = %d\n", blob_sizes.lbs_ipc);
-#ifdef CONFIG_KEYS
-       pr_info("LSM: key blob size        = %d\n", blob_sizes.lbs_key);
-#endif /* CONFIG_KEYS */
-       pr_info("LSM: msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
-       pr_info("LSM: sock blob size       = %d\n", blob_sizes.lbs_sock);
-       pr_info("LSM: superblock blob size = %d\n", blob_sizes.lbs_superblock);
        pr_info("LSM: task blob size       = %d\n", blob_sizes.lbs_task);
-#endif /* CONFIG_SECURITY_LSM_DEBUG */
+#endif
 
        return 0;
 }
@@ -381,19 +371,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed)
 {
        lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
        lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file);
-       lsm_set_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
-       lsm_set_size(&needed->lbs_key, &blob_sizes.lbs_key);
-       lsm_set_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
-       lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
-       lsm_set_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
        lsm_set_size(&needed->lbs_task, &blob_sizes.lbs_task);
-       /*
-        * The inode blob gets an rcu_head in addition to
-        * what the modules might need.
-        */
-       if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
-               blob_sizes.lbs_inode = sizeof(struct rcu_head);
-       lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
 }
 
 /**
@@ -508,166 +486,6 @@ int lsm_task_alloc(struct task_struct *task)
        return 0;
 }
 
-/**
- * lsm_inode_alloc - allocate a composite inode blob
- * @inode: the inode that needs a blob
- *
- * Allocate the inode blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_inode_alloc(struct inode *inode)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (inode->i_security)
-               pr_info("%s: Inbound inode blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_inode == 0)
-               return 0;
-
-       inode->i_security = kzalloc(blob_sizes.lbs_inode, GFP_KERNEL);
-       if (inode->i_security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
-/**
- * lsm_early_inode - during initialization allocate a composite inode blob
- * @inode: the inode that needs a blob
- *
- * Allocate the inode blob for all the modules if it's not already there
- */
-void lsm_early_inode(struct inode *inode)
-{
-       int rc;
-
-       if (inode == NULL)
-               panic("%s: NULL inode.\n", __func__);
-       if (inode->i_security != NULL)
-               return;
-       rc = lsm_inode_alloc(inode);
-       if (rc)
-               panic("%s: Early inode alloc failed.\n", __func__);
-}
-
-/**
- * lsm_ipc_alloc - allocate a composite ipc blob
- * @kip: the ipc that needs a blob
- *
- * Allocate the ipc blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_ipc_alloc(struct kern_ipc_perm *kip)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (kip->security)
-               pr_info("%s: Inbound ipc blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_ipc == 0)
-               return 0;
-
-       kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL);
-       if (kip->security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
-#ifdef CONFIG_KEYS
-/**
- * lsm_key_alloc - allocate a composite key blob
- * @key: the key that needs a blob
- *
- * Allocate the key blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_key_alloc(struct key *key)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (key->security)
-               pr_info("%s: Inbound key blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_key == 0)
-               return 0;
-
-       key->security = kzalloc(blob_sizes.lbs_key, GFP_KERNEL);
-       if (key->security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-#endif /* CONFIG_KEYS */
-
-/**
- * lsm_msg_msg_alloc - allocate a composite msg_msg blob
- * @mp: the msg_msg that needs a blob
- *
- * Allocate the ipc blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_msg_msg_alloc(struct msg_msg *mp)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (mp->security)
-               pr_info("%s: Inbound msg_msg blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_msg_msg == 0)
-               return 0;
-
-       mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL);
-       if (mp->security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
-/**
- * lsm_sock_alloc - allocate a composite sock blob
- * @sock: the sock that needs a blob
- * @priority: allocation mode
- *
- * Allocate the sock blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_sock_alloc(struct sock *sock, gfp_t priority)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (sock->sk_security)
-               pr_info("%s: Inbound sock blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_sock == 0)
-               return 0;
-
-       sock->sk_security = kzalloc(blob_sizes.lbs_sock, priority);
-       if (sock->sk_security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
-/**
- * lsm_superblock_alloc - allocate a composite superblock blob
- * @sb: the superblock that needs a blob
- *
- * Allocate the superblock blob for all the modules
- *
- * Returns 0, or -ENOMEM if memory can't be allocated.
- */
-int lsm_superblock_alloc(struct super_block *sb)
-{
-#ifdef CONFIG_SECURITY_LSM_DEBUG
-       if (sb->s_security)
-               pr_info("%s: Inbound superblock blob is not NULL.\n", __func__);
-#endif
-       if (blob_sizes.lbs_superblock == 0)
-               return 0;
-
-       sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL);
-       if (sb->s_security == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
 /*
  * Hook list operation macros.
  *
@@ -840,18 +658,12 @@ int security_bprm_secureexec(struct linux_binprm *bprm)
 
 int security_sb_alloc(struct super_block *sb)
 {
-       int rc = lsm_superblock_alloc(sb);
-
-       if (rc)
-               return rc;
        return call_int_hook(sb_alloc_security, 0, sb);
 }
 
 void security_sb_free(struct super_block *sb)
 {
        call_void_hook(sb_free_security, sb);
-       kfree(sb->s_security);
-       sb->s_security = NULL;
 }
 
 int security_sb_copy_data(char *orig, char *copy)
@@ -925,39 +737,14 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
 
 int security_inode_alloc(struct inode *inode)
 {
-       int rc = lsm_inode_alloc(inode);
-
-       if (rc)
-               return rc;
+       inode->i_security = NULL;
        return call_int_hook(inode_alloc_security, 0, inode);
 }
 
-static void inode_free_by_rcu(struct rcu_head *head)
-{
-       /*
-        * The rcu head is at the start of the inode blob
-        */
-       kfree(head);
-}
-
 void security_inode_free(struct inode *inode)
 {
        integrity_inode_free(inode);
        call_void_hook(inode_free_security, inode);
-       /*
-        * The inode may still be referenced in a path walk and
-        * a call to security_inode_permission() can be made
-        * after inode_free_security() is called. Ideally, the VFS
-        * wouldn't do this, but fixing that is a much harder
-        * job. For now, simply free the i_security via RCU, and
-        * leave the current inode->i_security pointer intact.
-        * The inode will be freed after the RCU grace period too.
-        */
-       if (inode->i_security != NULL) {
-               call_rcu((struct rcu_head *)inode->i_security,
-                               inode_free_by_rcu);
-               inode->i_security = NULL;
-       }
 }
 
 int security_dentry_init_security(struct dentry *dentry, int mode,
@@ -1794,36 +1581,22 @@ void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
 
 int security_msg_msg_alloc(struct msg_msg *msg)
 {
-       int rc = lsm_msg_msg_alloc(msg);
-
-       if (rc)
-               return rc;
        return call_int_hook(msg_msg_alloc_security, 0, msg);
 }
 
 void security_msg_msg_free(struct msg_msg *msg)
 {
        call_void_hook(msg_msg_free_security, msg);
-       kfree(msg->security);
-       msg->security = NULL;
 }
 
 int security_msg_queue_alloc(struct msg_queue *msq)
 {
-       int rc = lsm_ipc_alloc(&msq->q_perm);
-
-       if (rc)
-               return rc;
        return call_int_hook(msg_queue_alloc_security, 0, msq);
 }
 
 void security_msg_queue_free(struct msg_queue *msq)
 {
-       struct kern_ipc_perm *kip = &msq->q_perm;
-
        call_void_hook(msg_queue_free_security, msq);
-       kfree(kip->security);
-       kip->security = NULL;
 }
 
 int security_msg_queue_associate(struct msg_queue *msq, int msqflg)
@@ -1850,20 +1623,12 @@ int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 
 int security_shm_alloc(struct shmid_kernel *shp)
 {
-       int rc = lsm_ipc_alloc(&shp->shm_perm);
-
-       if (rc)
-               return rc;
        return call_int_hook(shm_alloc_security, 0, shp);
 }
 
 void security_shm_free(struct shmid_kernel *shp)
 {
-       struct kern_ipc_perm *kip = &shp->shm_perm;
-
        call_void_hook(shm_free_security, shp);
-       kfree(kip->security);
-       kip->security = NULL;
 }
 
 int security_shm_associate(struct shmid_kernel *shp, int shmflg)
@@ -1883,20 +1648,12 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl
 
 int security_sem_alloc(struct sem_array *sma)
 {
-       int rc = lsm_ipc_alloc(&sma->sem_perm);
-
-       if (rc)
-               return rc;
        return call_int_hook(sem_alloc_security, 0, sma);
 }
 
 void security_sem_free(struct sem_array *sma)
 {
-       struct kern_ipc_perm *kip = &sma->sem_perm;
-
        call_void_hook(sem_free_security, sma);
-       kfree(kip->security);
-       kip->security = NULL;
 }
 
 int security_sem_associate(struct sem_array *sma, int semflg)
@@ -2287,18 +2044,12 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram);
 
 int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
 {
-       int rc = lsm_sock_alloc(sk, priority);
-
-       if (rc)
-               return rc;
        return call_int_hook(sk_alloc_security, 0, sk, family, priority);
 }
 
 void security_sk_free(struct sock *sk)
 {
        call_void_hook(sk_free_security, sk);
-       kfree(sk->sk_security);
-       sk->sk_security = NULL;
 }
 
 void security_sk_clone(const struct sock *sk, struct sock *newsk)
@@ -2528,18 +2279,12 @@ EXPORT_SYMBOL(security_skb_classify_flow);
 int security_key_alloc(struct key *key, const struct cred *cred,
                       unsigned long flags)
 {
-       int rc = lsm_key_alloc(key);
-
-       if (rc)
-               return rc;
        return call_int_hook(key_alloc, 0, key, cred, flags);
 }
 
 void security_key_free(struct key *key)
 {
        call_void_hook(key_free, key);
-       kfree(key->security);
-       key->security = NULL;
 }
 
 int security_key_permission(key_ref_t key_ref,
index b6dd89f8e52280e856509462391fdda795a39160..cd01d84e012ea566192dd079aac36770181dca43 100644 (file)
@@ -128,6 +128,8 @@ __setup("selinux=", selinux_enabled_setup);
 int selinux_enabled = 1;
 #endif
 
+static struct kmem_cache *sel_inode_cache;
+
 /**
  * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
  *
@@ -221,9 +223,13 @@ static inline u32 task_sid(const struct task_struct *task)
 
 static int inode_alloc_security(struct inode *inode)
 {
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec;
        u32 sid = current_sid();
 
+       isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS);
+       if (!isec)
+               return -ENOMEM;
+
        spin_lock_init(&isec->lock);
        INIT_LIST_HEAD(&isec->list);
        isec->inode = inode;
@@ -231,6 +237,7 @@ static int inode_alloc_security(struct inode *inode)
        isec->sclass = SECCLASS_FILE;
        isec->task_sid = sid;
        isec->initialized = LABEL_INVALID;
+       inode->i_security = isec;
 
        return 0;
 }
@@ -248,7 +255,7 @@ static int __inode_security_revalidate(struct inode *inode,
                                       struct dentry *opt_dentry,
                                       bool may_sleep)
 {
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec = inode->i_security;
 
        might_sleep_if(may_sleep);
 
@@ -268,7 +275,7 @@ static int __inode_security_revalidate(struct inode *inode,
 
 static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
 {
-       return selinux_inode(inode);
+       return inode->i_security;
 }
 
 static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
@@ -278,7 +285,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo
        error = __inode_security_revalidate(inode, NULL, !rcu);
        if (error)
                return ERR_PTR(error);
-       return selinux_inode(inode);
+       return inode->i_security;
 }
 
 /*
@@ -287,14 +294,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo
 static struct inode_security_struct *inode_security(struct inode *inode)
 {
        __inode_security_revalidate(inode, NULL, true);
-       return selinux_inode(inode);
+       return inode->i_security;
 }
 
 static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
 {
        struct inode *inode = d_backing_inode(dentry);
 
-       return selinux_inode(inode);
+       return inode->i_security;
 }
 
 /*
@@ -305,14 +312,21 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr
        struct inode *inode = d_backing_inode(dentry);
 
        __inode_security_revalidate(inode, dentry, true);
-       return selinux_inode(inode);
+       return inode->i_security;
+}
+
+static void inode_free_rcu(struct rcu_head *head)
+{
+       struct inode_security_struct *isec;
+
+       isec = container_of(head, struct inode_security_struct, rcu);
+       kmem_cache_free(sel_inode_cache, isec);
 }
 
 static void inode_free_security(struct inode *inode)
 {
-       struct inode_security_struct *isec = selinux_inode(inode);
-       struct superblock_security_struct *sbsec =
-                                       selinux_superblock(inode->i_sb);
+       struct inode_security_struct *isec = inode->i_security;
+       struct superblock_security_struct *sbsec = inode->i_sb->s_security;
 
        /*
         * As not all inode security structures are in a list, we check for
@@ -329,6 +343,17 @@ static void inode_free_security(struct inode *inode)
                list_del_init(&isec->list);
                spin_unlock(&sbsec->isec_lock);
        }
+
+       /*
+        * The inode may still be referenced in a path walk and
+        * a call to selinux_inode_permission() can be made
+        * after inode_free_security() is called. Ideally, the VFS
+        * wouldn't do this, but fixing that is a much harder
+        * job. For now, simply free the i_security via RCU, and
+        * leave the current inode->i_security pointer intact.
+        * The inode will be freed after the RCU grace period too.
+        */
+       call_rcu(&isec->rcu, inode_free_rcu);
 }
 
 static int file_alloc_security(struct file *file)
@@ -344,7 +369,11 @@ static int file_alloc_security(struct file *file)
 
 static int superblock_alloc_security(struct super_block *sb)
 {
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec;
+
+       sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+       if (!sbsec)
+               return -ENOMEM;
 
        mutex_init(&sbsec->lock);
        INIT_LIST_HEAD(&sbsec->isec_head);
@@ -353,10 +382,18 @@ static int superblock_alloc_security(struct super_block *sb)
        sbsec->sid = SECINITSID_UNLABELED;
        sbsec->def_sid = SECINITSID_FILE;
        sbsec->mntpoint_sid = SECINITSID_UNLABELED;
+       sb->s_security = sbsec;
 
        return 0;
 }
 
+static void superblock_free_security(struct super_block *sb)
+{
+       struct superblock_security_struct *sbsec = sb->s_security;
+       sb->s_security = NULL;
+       kfree(sbsec);
+}
+
 static inline int inode_doinit(struct inode *inode)
 {
        return inode_doinit_with_dentry(inode, NULL);
@@ -420,7 +457,7 @@ static int may_context_mount_inode_relabel(u32 sid,
 
 static int selinux_is_sblabel_mnt(struct super_block *sb)
 {
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
 
        return sbsec->behavior == SECURITY_FS_USE_XATTR ||
                sbsec->behavior == SECURITY_FS_USE_TRANS ||
@@ -439,7 +476,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
 
 static int sb_finish_set_opts(struct super_block *sb)
 {
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
        struct dentry *root = sb->s_root;
        struct inode *root_inode = d_backing_inode(root);
        int rc = 0;
@@ -522,7 +559,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
                                struct security_mnt_opts *opts)
 {
        int rc = 0, i;
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
        char *context = NULL;
        u32 len;
        char tmp;
@@ -585,8 +622,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
        }
        if (sbsec->flags & ROOTCONTEXT_MNT) {
                struct dentry *root = sbsec->sb->s_root;
-               struct inode_security_struct *isec =
-                                               backing_inode_security(root);
+               struct inode_security_struct *isec = backing_inode_security(root);
 
                rc = security_sid_to_context(isec->sid, &context, &len);
                if (rc)
@@ -639,7 +675,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 {
        const struct cred *cred = current_cred();
        int rc = 0, i;
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
        const char *name = sb->s_type->name;
        struct dentry *root = sbsec->sb->s_root;
        struct inode_security_struct *root_isec;
@@ -888,8 +924,8 @@ out_double_mount:
 static int selinux_cmp_sb_context(const struct super_block *oldsb,
                                    const struct super_block *newsb)
 {
-       struct superblock_security_struct *old = selinux_superblock(oldsb);
-       struct superblock_security_struct *new = selinux_superblock(newsb);
+       struct superblock_security_struct *old = oldsb->s_security;
+       struct superblock_security_struct *new = newsb->s_security;
        char oldflags = old->flags & SE_MNTMASK;
        char newflags = new->flags & SE_MNTMASK;
 
@@ -921,9 +957,8 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
                                        unsigned long *set_kern_flags)
 {
        int rc = 0;
-       const struct superblock_security_struct *oldsbsec =
-                                               selinux_superblock(oldsb);
-       struct superblock_security_struct *newsbsec = selinux_superblock(newsb);
+       const struct superblock_security_struct *oldsbsec = oldsb->s_security;
+       struct superblock_security_struct *newsbsec = newsb->s_security;
 
        int set_fscontext =     (oldsbsec->flags & FSCONTEXT_MNT);
        int set_context =       (oldsbsec->flags & CONTEXT_MNT);
@@ -976,17 +1011,14 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
                if (!set_fscontext)
                        newsbsec->sid = sid;
                if (!set_rootcontext) {
-                       struct inode_security_struct *newisec =
-                                       backing_inode_security(newsb->s_root);
+                       struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
                        newisec->sid = sid;
                }
                newsbsec->mntpoint_sid = sid;
        }
        if (set_rootcontext) {
-               const struct inode_security_struct *oldisec =
-                                       backing_inode_security(oldsb->s_root);
-               struct inode_security_struct *newisec =
-                                       backing_inode_security(newsb->s_root);
+               const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
+               struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
 
                newisec->sid = oldisec->sid;
        }
@@ -1429,7 +1461,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
 static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
 {
        struct superblock_security_struct *sbsec = NULL;
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec = inode->i_security;
        u32 task_sid, sid = 0;
        u16 sclass;
        struct dentry *dentry;
@@ -1448,7 +1480,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
        if (isec->sclass == SECCLASS_FILE)
                isec->sclass = inode_mode_to_security_class(inode->i_mode);
 
-       sbsec = selinux_superblock(inode->i_sb);
+       sbsec = inode->i_sb->s_security;
        if (!(sbsec->flags & SE_SBINITIALIZED)) {
                /* Defer initialization until selinux_complete_init,
                   after the initial policy is loaded and the security
@@ -1714,7 +1746,7 @@ static int inode_has_perm(const struct cred *cred,
                return 0;
 
        sid = cred_sid(cred);
-       isec = selinux_inode(inode);
+       isec = inode->i_security;
 
        return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
 }
@@ -1811,8 +1843,7 @@ selinux_determine_inode_label(const struct task_security_struct *tsec,
                                 const struct qstr *name, u16 tclass,
                                 u32 *_new_isid)
 {
-       const struct superblock_security_struct *sbsec =
-                                               selinux_superblock(dir->i_sb);
+       const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
 
        if ((sbsec->flags & SE_SBINITIALIZED) &&
            (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
@@ -1842,7 +1873,7 @@ static int may_create(struct inode *dir,
        int rc;
 
        dsec = inode_security(dir);
-       sbsec = selinux_superblock(dir->i_sb);
+       sbsec = dir->i_sb->s_security;
 
        sid = tsec->sid;
 
@@ -1981,7 +2012,7 @@ static int superblock_has_perm(const struct cred *cred,
        struct superblock_security_struct *sbsec;
        u32 sid = cred_sid(cred);
 
-       sbsec = selinux_superblock(sb);
+       sbsec = sb->s_security;
        return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
 }
 
@@ -2576,6 +2607,11 @@ static int selinux_sb_alloc_security(struct super_block *sb)
        return superblock_alloc_security(sb);
 }
 
+static void selinux_sb_free_security(struct super_block *sb)
+{
+       superblock_free_security(sb);
+}
+
 static inline int match_prefix(char *prefix, int plen, char *option, int olen)
 {
        if (plen > olen)
@@ -2672,7 +2708,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
        int rc, i, *flags;
        struct security_mnt_opts opts;
        char *secdata, **mount_options;
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
 
        if (!(sbsec->flags & SE_SBINITIALIZED))
                return 0;
@@ -2863,7 +2899,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
        int rc;
        char *context;
 
-       sbsec = selinux_superblock(dir->i_sb);
+       sbsec = dir->i_sb->s_security;
 
        sid = tsec->sid;
        newsid = tsec->create_sid;
@@ -2877,7 +2913,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 
        /* Possibly defer initialization to selinux_complete_init. */
        if (sbsec->flags & SE_SBINITIALIZED) {
-               struct inode_security_struct *isec = selinux_inode(inode);
+               struct inode_security_struct *isec = inode->i_security;
                isec->sclass = inode_mode_to_security_class(inode->i_mode);
                isec->sid = newsid;
                isec->initialized = LABEL_INITIALIZED;
@@ -2975,7 +3011,7 @@ static noinline int audit_inode_permission(struct inode *inode,
                                           unsigned flags)
 {
        struct common_audit_data ad;
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec = inode->i_security;
        int rc;
 
        ad.type = LSM_AUDIT_DATA_INODE;
@@ -3111,7 +3147,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
        if (strcmp(name, XATTR_NAME_SELINUX))
                return selinux_inode_setotherxattr(dentry, name);
 
-       sbsec = selinux_superblock(inode->i_sb);
+       sbsec = inode->i_sb->s_security;
        if (!(sbsec->flags & SBLABEL_MNT))
                return -EOPNOTSUPP;
 
@@ -3944,7 +3980,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
 static void selinux_task_to_inode(struct task_struct *p,
                                  struct inode *inode)
 {
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec = inode->i_security;
        u32 sid = task_sid(p);
 
        spin_lock(&isec->lock);
@@ -4230,7 +4266,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec,
 
 static int sock_has_perm(struct sock *sk, u32 perms)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
 
@@ -4285,7 +4321,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
        isec->initialized = LABEL_INITIALIZED;
 
        if (sock->sk) {
-               sksec = selinux_sock(sock->sk);
+               sksec = sock->sk->sk_security;
                sksec->sclass = sclass;
                sksec->sid = sid;
                err = selinux_netlbl_socket_post_create(sock->sk, family);
@@ -4316,7 +4352,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
        family = sk->sk_family;
        if (family == PF_INET || family == PF_INET6) {
                char *addrp;
-               struct sk_security_struct *sksec = selinux_sock(sk);
+               struct sk_security_struct *sksec = sk->sk_security;
                struct common_audit_data ad;
                struct lsm_network_audit net = {0,};
                struct sockaddr_in *addr4 = NULL;
@@ -4409,7 +4445,7 @@ out:
 static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
 {
        struct sock *sk = sock->sk;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        int err;
 
        err = sock_has_perm(sk, SOCKET__CONNECT);
@@ -4541,9 +4577,9 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
                                              struct sock *other,
                                              struct sock *newsk)
 {
-       struct sk_security_struct *sksec_sock = selinux_sock(sock);
-       struct sk_security_struct *sksec_other = selinux_sock(other);
-       struct sk_security_struct *sksec_new = selinux_sock(newsk);
+       struct sk_security_struct *sksec_sock = sock->sk_security;
+       struct sk_security_struct *sksec_other = other->sk_security;
+       struct sk_security_struct *sksec_new = newsk->sk_security;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
        int err;
@@ -4574,8 +4610,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
 static int selinux_socket_unix_may_send(struct socket *sock,
                                        struct socket *other)
 {
-       struct sk_security_struct *ssec = selinux_sock(sock->sk);
-       struct sk_security_struct *osec = selinux_sock(other->sk);
+       struct sk_security_struct *ssec = sock->sk->sk_security;
+       struct sk_security_struct *osec = other->sk->sk_security;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
 
@@ -4614,7 +4650,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
                                       u16 family)
 {
        int err = 0;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
        struct lsm_network_audit net = {0,};
@@ -4646,7 +4682,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int err;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        u16 family = sk->sk_family;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
@@ -4712,15 +4748,13 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        return err;
 }
 
-static int selinux_socket_getpeersec_stream(struct socket *sock,
-                                           __user char *optval,
-                                           __user int *optlen,
-                                           unsigned int len)
+static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+                                           int __user *optlen, unsigned len)
 {
        int err = 0;
        char *scontext;
        u32 scontext_len;
-       struct sk_security_struct *sksec = selinux_sock(sock->sk);
+       struct sk_security_struct *sksec = sock->sk->sk_security;
        u32 peer_sid = SECSID_NULL;
 
        if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
@@ -4778,27 +4812,34 @@ out:
 
 static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec;
+
+       sksec = kzalloc(sizeof(*sksec), priority);
+       if (!sksec)
+               return -ENOMEM;
 
        sksec->peer_sid = SECINITSID_UNLABELED;
        sksec->sid = SECINITSID_UNLABELED;
        sksec->sclass = SECCLASS_SOCKET;
        selinux_netlbl_sk_security_reset(sksec);
+       sk->sk_security = sksec;
 
        return 0;
 }
 
 static void selinux_sk_free_security(struct sock *sk)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
+       sk->sk_security = NULL;
        selinux_netlbl_sk_security_free(sksec);
+       kfree(sksec);
 }
 
 static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
-       struct sk_security_struct *newsksec = selinux_sock(newsk);
+       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *newsksec = newsk->sk_security;
 
        newsksec->sid = sksec->sid;
        newsksec->peer_sid = sksec->peer_sid;
@@ -4812,7 +4853,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
        if (!sk)
                *secid = SECINITSID_ANY_SOCKET;
        else {
-               struct sk_security_struct *sksec = selinux_sock(sk);
+               struct sk_security_struct *sksec = sk->sk_security;
 
                *secid = sksec->sid;
        }
@@ -4822,7 +4863,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
 {
        struct inode_security_struct *isec =
                inode_security_novalidate(SOCK_INODE(parent));
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
        if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
            sk->sk_family == PF_UNIX)
@@ -4833,7 +4874,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
 static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
                                     struct request_sock *req)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        int err;
        u16 family = req->rsk_ops->family;
        u32 connsid;
@@ -4854,7 +4895,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 static void selinux_inet_csk_clone(struct sock *newsk,
                                   const struct request_sock *req)
 {
-       struct sk_security_struct *newsksec = selinux_sock(newsk);
+       struct sk_security_struct *newsksec = newsk->sk_security;
 
        newsksec->sid = req->secid;
        newsksec->peer_sid = req->peer_secid;
@@ -4871,7 +4912,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
 static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
 {
        u16 family = sk->sk_family;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
        /* handle mapped IPv4 packets arriving via IPv6 sockets */
        if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -4951,7 +4992,7 @@ static int selinux_tun_dev_attach_queue(void *security)
 static int selinux_tun_dev_attach(struct sock *sk, void *security)
 {
        struct tun_security_struct *tunsec = security;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
        /* we don't currently perform any NetLabel based labeling here and it
         * isn't clear that we would want to do so anyway; while we could apply
@@ -4990,7 +5031,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
        int err = 0;
        u32 perm;
        struct nlmsghdr *nlh;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
        if (skb->len < NLMSG_HDRLEN) {
                err = -EINVAL;
@@ -5129,7 +5170,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
                        return NF_ACCEPT;
 
                /* standard practice, label using the parent socket */
-               sksec = selinux_sock(sk);
+               sksec = sk->sk_security;
                sid = sksec->sid;
        } else
                sid = SECINITSID_KERNEL;
@@ -5168,7 +5209,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 
        if (sk == NULL)
                return NF_ACCEPT;
-       sksec = selinux_sock(sk);
+       sksec = sk->sk_security;
 
        ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
@@ -5259,7 +5300,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
                u32 skb_sid;
                struct sk_security_struct *sksec;
 
-               sksec = selinux_sock(sk);
+               sksec = sk->sk_security;
                if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
                        return NF_DROP;
                /* At this point, if the returned skb peerlbl is SECSID_NULL
@@ -5288,7 +5329,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
        } else {
                /* Locally generated packet, fetch the security label from the
                 * associated socket. */
-               struct sk_security_struct *sksec = selinux_sock(sk);
+               struct sk_security_struct *sksec = sk->sk_security;
                peer_sid = sksec->sid;
                secmark_perm = PACKET__SEND;
        }
@@ -5348,22 +5389,51 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
        return selinux_nlmsg_perm(sk, skb);
 }
 
-static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)
+static int ipc_alloc_security(struct kern_ipc_perm *perm,
+                             u16 sclass)
 {
+       struct ipc_security_struct *isec;
+
+       isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+       if (!isec)
+               return -ENOMEM;
+
        isec->sclass = sclass;
        isec->sid = current_sid();
+       perm->security = isec;
+
+       return 0;
+}
+
+static void ipc_free_security(struct kern_ipc_perm *perm)
+{
+       struct ipc_security_struct *isec = perm->security;
+       perm->security = NULL;
+       kfree(isec);
 }
 
 static int msg_msg_alloc_security(struct msg_msg *msg)
 {
        struct msg_security_struct *msec;
 
-       msec = selinux_msg_msg(msg);
+       msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+       if (!msec)
+               return -ENOMEM;
+
        msec->sid = SECINITSID_UNLABELED;
+       msg->security = msec;
 
        return 0;
 }
 
+static void msg_msg_free_security(struct msg_msg *msg)
+{
+       struct msg_security_struct *msec = msg->security;
+
+       msg->security = NULL;
+       kfree(msec);
+}
+
 static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
                        u32 perms)
 {
@@ -5371,7 +5441,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = selinux_ipc(ipc_perms);
+       isec = ipc_perms->security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = ipc_perms->key;
@@ -5384,6 +5454,11 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
        return msg_msg_alloc_security(msg);
 }
 
+static void selinux_msg_msg_free_security(struct msg_msg *msg)
+{
+       msg_msg_free_security(msg);
+}
+
 /* message queue security operations */
 static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
 {
@@ -5392,15 +5467,27 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
        u32 sid = current_sid();
        int rc;
 
-       isec = selinux_ipc(&msq->q_perm);
-       ipc_init_security(isec, SECCLASS_MSGQ);
+       rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ);
+       if (rc)
+               return rc;
+
+       isec = msq->q_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
                          MSGQ__CREATE, &ad);
-       return rc;
+       if (rc) {
+               ipc_free_security(&msq->q_perm);
+               return rc;
+       }
+       return 0;
+}
+
+static void selinux_msg_queue_free_security(struct msg_queue *msq)
+{
+       ipc_free_security(&msq->q_perm);
 }
 
 static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
@@ -5409,7 +5496,7 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = selinux_ipc(&msq->q_perm);
+       isec = msq->q_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
@@ -5455,8 +5542,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
        u32 sid = current_sid();
        int rc;
 
-       isec = selinux_ipc(&msq->q_perm);
-       msec = selinux_msg_msg(msg);
+       isec = msq->q_perm.security;
+       msec = msg->security;
 
        /*
         * First time through, need to assign label to the message
@@ -5500,8 +5587,8 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
        u32 sid = task_sid(target);
        int rc;
 
-       isec = selinux_ipc(&msq->q_perm);
-       msec = selinux_msg_msg(msg);
+       isec = msq->q_perm.security;
+       msec = msg->security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
@@ -5522,15 +5609,27 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
        u32 sid = current_sid();
        int rc;
 
-       isec = selinux_ipc(&shp->shm_perm);
-       ipc_init_security(isec, SECCLASS_SHM);
+       rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM);
+       if (rc)
+               return rc;
+
+       isec = shp->shm_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
                          SHM__CREATE, &ad);
-       return rc;
+       if (rc) {
+               ipc_free_security(&shp->shm_perm);
+               return rc;
+       }
+       return 0;
+}
+
+static void selinux_shm_free_security(struct shmid_kernel *shp)
+{
+       ipc_free_security(&shp->shm_perm);
 }
 
 static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
@@ -5539,7 +5638,7 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = selinux_ipc(&shp->shm_perm);
+       isec = shp->shm_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
@@ -5603,15 +5702,27 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
        u32 sid = current_sid();
        int rc;
 
-       isec = selinux_ipc(&sma->sem_perm);
-       ipc_init_security(isec, SECCLASS_SEM);
+       rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM);
+       if (rc)
+               return rc;
+
+       isec = sma->sem_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
                          SEM__CREATE, &ad);
-       return rc;
+       if (rc) {
+               ipc_free_security(&sma->sem_perm);
+               return rc;
+       }
+       return 0;
+}
+
+static void selinux_sem_free_security(struct sem_array *sma)
+{
+       ipc_free_security(&sma->sem_perm);
 }
 
 static int selinux_sem_associate(struct sem_array *sma, int semflg)
@@ -5620,7 +5731,7 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg)
        struct common_audit_data ad;
        u32 sid = current_sid();
 
-       isec = selinux_ipc(&sma->sem_perm);
+       isec = sma->sem_perm.security;
 
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
@@ -5703,7 +5814,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 
 static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
 {
-       struct ipc_security_struct *isec = selinux_ipc(ipcp);
+       struct ipc_security_struct *isec = ipcp->security;
        *secid = isec->sid;
 }
 
@@ -5930,7 +6041,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
 
 static void selinux_inode_invalidate_secctx(struct inode *inode)
 {
-       struct inode_security_struct *isec = selinux_inode(inode);
+       struct inode_security_struct *isec = inode->i_security;
 
        spin_lock(&isec->lock);
        isec->initialized = LABEL_INVALID;
@@ -5969,7 +6080,11 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred,
                             unsigned long flags)
 {
        const struct task_security_struct *tsec;
-       struct key_security_struct *ksec = selinux_key(k);
+       struct key_security_struct *ksec;
+
+       ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
+       if (!ksec)
+               return -ENOMEM;
 
        tsec = selinux_cred(cred);
        if (tsec->keycreate_sid)
@@ -5977,9 +6092,18 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred,
        else
                ksec->sid = tsec->sid;
 
+       k->security = ksec;
        return 0;
 }
 
+static void selinux_key_free(struct key *k)
+{
+       struct key_security_struct *ksec = k->security;
+
+       k->security = NULL;
+       kfree(ksec);
+}
+
 static int selinux_key_permission(key_ref_t key_ref,
                                  const struct cred *cred,
                                  unsigned perm)
@@ -5997,14 +6121,14 @@ static int selinux_key_permission(key_ref_t key_ref,
        sid = cred_sid(cred);
 
        key = key_ref_to_ptr(key_ref);
-       ksec = selinux_key(key);
+       ksec = key->security;
 
        return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
 }
 
 static int selinux_key_getsecurity(struct key *key, char **_buffer)
 {
-       struct key_security_struct *ksec = selinux_key(key);
+       struct key_security_struct *ksec = key->security;
        char *context = NULL;
        unsigned len;
        int rc;
@@ -6084,14 +6208,6 @@ static void selinux_ib_free_security(void *ib_sec)
 struct lsm_blob_sizes selinux_blob_sizes = {
        .lbs_cred = sizeof(struct task_security_struct),
        .lbs_file = sizeof(struct file_security_struct),
-       .lbs_inode = sizeof(struct inode_security_struct),
-       .lbs_ipc = sizeof(struct ipc_security_struct),
-#ifdef CONFIG_KEYS
-       .lbs_key = sizeof(struct key_security_struct),
-#endif /* CONFIG_KEYS */
-       .lbs_msg_msg = sizeof(struct msg_security_struct),
-       .lbs_sock = sizeof(struct sk_security_struct),
-       .lbs_superblock = sizeof(struct superblock_security_struct),
 };
 
 static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
@@ -6118,6 +6234,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec),
 
        LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
+       LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
        LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data),
        LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
        LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
@@ -6200,20 +6317,24 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
 
        LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
+       LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security),
 
        LSM_HOOK_INIT(msg_queue_alloc_security,
                        selinux_msg_queue_alloc_security),
+       LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security),
        LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
        LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
        LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
        LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
 
        LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
+       LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security),
        LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
        LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
        LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
 
        LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
+       LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security),
        LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
        LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
        LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
@@ -6295,6 +6416,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
 
 #ifdef CONFIG_KEYS
        LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
+       LSM_HOOK_INIT(key_free, selinux_key_free),
        LSM_HOOK_INIT(key_permission, selinux_key_permission),
        LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
 #endif
@@ -6335,6 +6457,9 @@ static __init int selinux_init(void)
 
        default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
 
+       sel_inode_cache = kmem_cache_create("selinux_inode_security",
+                                           sizeof(struct inode_security_struct),
+                                           0, SLAB_PANIC, NULL);
        avc_init();
 
        security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
index 306863675614956e0d7a7aee2b1e82067d513ad6..e502078d6542585477d2f0ced72c258b0cfd5402 100644 (file)
@@ -59,7 +59,10 @@ enum label_initialized {
 
 struct inode_security_struct {
        struct inode *inode;    /* back pointer to inode object */
-       struct list_head list;  /* list of inode_security_struct */
+       union {
+               struct list_head list;  /* list of inode_security_struct */
+               struct rcu_head rcu;    /* for freeing the inode_security_struct */
+       };
        u32 task_sid;           /* SID of creating task */
        u32 sid;                /* SID of this object */
        u16 sclass;             /* security class of this object */
@@ -171,64 +174,4 @@ static inline struct file_security_struct *selinux_file(const struct file *file)
 #endif
 }
 
-static inline struct inode_security_struct *selinux_inode(
-                                               const struct inode *inode)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return inode->i_security + selinux_blob_sizes.lbs_inode;
-#else
-       return inode->i_security;
-#endif
-}
-
-static inline struct superblock_security_struct *selinux_superblock(
-                                       const struct super_block *superblock)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return superblock->s_security + selinux_blob_sizes.lbs_superblock;
-#else
-       return superblock->s_security;
-#endif
-}
-
-static inline struct msg_security_struct *selinux_msg_msg(
-                                               const struct msg_msg *msg_msg)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return msg_msg->security + selinux_blob_sizes.lbs_msg_msg;
-#else
-       return msg_msg->security;
-#endif
-}
-
-static inline struct ipc_security_struct *selinux_ipc(
-                                               const struct kern_ipc_perm *ipc)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return ipc->security + selinux_blob_sizes.lbs_ipc;
-#else
-       return ipc->security;
-#endif
-}
-
-#ifdef CONFIG_KEYS
-static inline struct key_security_struct *selinux_key(const struct key *key)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return key->security + selinux_blob_sizes.lbs_key;
-#else
-       return key->security;
-#endif
-}
-#endif /* CONFIG_KEYS */
-
-static inline struct sk_security_struct *selinux_sock(const struct sock *sock)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return sock->sk_security + selinux_blob_sizes.lbs_sock;
-#else
-       return sock->sk_security;
-#endif
-}
-
 #endif /* _SELINUX_OBJSEC_H_ */
index 0b0091c0468802fab7ffdcf7756370a296b6a0e4..aaba6677ee2e62c84cfe7211803c1b077294d00c 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/gfp.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
-#include <linux/lsm_hooks.h>
 #include <net/sock.h>
 #include <net/netlabel.h>
 #include <net/ip.h>
@@ -83,7 +82,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
 static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
 {
        int rc;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr *secattr;
 
        if (sksec->nlbl_secattr != NULL)
@@ -115,7 +114,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
                                                        const struct sock *sk,
                                                        u32 sid)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
 
        if (secattr == NULL)
@@ -250,7 +249,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
         * being labeled by it's parent socket, if it is just exit */
        sk = skb_to_full_sk(skb);
        if (sk != NULL) {
-               struct sk_security_struct *sksec = selinux_sock(sk);
+               struct sk_security_struct *sksec = sk->sk_security;
                if (sksec->nlbl_state != NLBL_REQSKB)
                        return 0;
                secattr = selinux_netlbl_sock_getattr(sk, sid);
@@ -312,7 +311,7 @@ inet_conn_request_return:
  */
 void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
 {
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
 
        if (family == PF_INET)
                sksec->nlbl_state = NLBL_LABELED;
@@ -333,7 +332,7 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
 int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
 {
        int rc;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr *secattr;
 
        if (family != PF_INET && family != PF_INET6)
@@ -447,7 +446,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
 {
        int rc = 0;
        struct sock *sk = sock->sk;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
 
        if (selinux_netlbl_option(level, optname) &&
@@ -483,7 +482,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
 {
        int rc;
-       struct sk_security_struct *sksec = selinux_sock(sk);
+       struct sk_security_struct *sksec = sk->sk_security;
        struct netlbl_lsm_secattr *secattr;
 
        if (sksec->nlbl_state != NLBL_REQSKB &&
index 1b4bed79101e6e15e62cb0a29babe00f6698771c..855a13053a81af934da468a6f4b738bc1d782639 100644 (file)
@@ -1300,7 +1300,7 @@ static int sel_make_bools(void)
                if (len >= PAGE_SIZE)
                        goto out;
 
-               isec = (struct inode_security_struct *)selinux_inode(inode);
+               isec = (struct inode_security_struct *)inode->i_security;
                ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
                if (ret) {
                        pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
@@ -1841,7 +1841,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
                goto err;
 
        inode->i_ino = ++sel_last_ino;
-       isec = (struct inode_security_struct *)selinux_inode(inode);
+       isec = (struct inode_security_struct *)inode->i_security;
        isec->sid = SECINITSID_DEVNULL;
        isec->sclass = SECCLASS_CHR_FILE;
        isec->initialized = LABEL_INITIALIZED;
index 4558a23d160e54c0b32d2c9b1c091a4cf8f2e957..2f02fa67ec2e833eefb6f98f9d6190f4012679a1 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/selinux.h>
 #include <linux/flex_array.h>
 #include <linux/vmalloc.h>
-#include <linux/lsm_hooks.h>
 #include <net/netlabel.h>
 
 #include "flask.h"
@@ -2655,7 +2654,7 @@ int security_fs_use(struct super_block *sb)
 {
        int rc = 0;
        struct ocontext *c;
-       struct superblock_security_struct *sbsec = selinux_superblock(sb);
+       struct superblock_security_struct *sbsec = sb->s_security;
        const char *fstype = sb->s_type->name;
 
        read_lock(&policy_rwlock);
index e7611de071f155ea7ee1cb2df93587209e2b68b9..55ef0015035be37c241bffe985f4b1dafa61a45d 100644 (file)
@@ -375,69 +375,12 @@ static inline struct smack_known **smack_file(const struct file *file)
 #endif
 }
 
-static inline struct inode_smack *smack_inode(const struct inode *inode)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return inode->i_security + smack_blob_sizes.lbs_inode;
-#else
-       return inode->i_security;
-#endif
-}
-
-static inline struct socket_smack *smack_sock(const struct sock *sock)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return sock->sk_security + smack_blob_sizes.lbs_sock;
-#else
-       return sock->sk_security;
-#endif
-}
-
-static inline struct superblock_smack *smack_superblock(
-                                       const struct super_block *superblock)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return superblock->s_security + smack_blob_sizes.lbs_superblock;
-#else
-       return superblock->s_security;
-#endif
-}
-
-static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return msg->security + smack_blob_sizes.lbs_msg_msg;
-#else
-       return msg->security;
-#endif
-}
-
-static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return ipc->security + smack_blob_sizes.lbs_ipc;
-#else
-       return ipc->security;
-#endif
-}
-
-#ifdef CONFIG_KEYS
-static inline struct smack_known **smack_key(const struct key *key)
-{
-#ifdef CONFIG_SECURITY_STACKING
-       return key->security + smack_blob_sizes.lbs_key;
-#else
-       return key->security;
-#endif
-}
-#endif /* CONFIG_KEYS */
-
 /*
  * Is the directory transmuting?
  */
 static inline int smk_inode_transmutable(const struct inode *isp)
 {
-       struct inode_smack *sip = smack_inode(isp);
+       struct inode_smack *sip = isp->i_security;
        return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
 }
 
@@ -446,7 +389,7 @@ static inline int smk_inode_transmutable(const struct inode *isp)
  */
 static inline struct smack_known *smk_of_inode(const struct inode *isp)
 {
-       struct inode_smack *sip = smack_inode(isp);
+       struct inode_smack *sip = isp->i_security;
        return sip->smk_inode;
 }
 
index 901b293925dc547c819d35ed4ed0caf9caedcbda..cd27113520ac55a5315c1d5ec6ffccfcfbd70e24 100644 (file)
@@ -165,7 +165,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
 static int smk_bu_inode(struct inode *inode, int mode, int rc)
 {
        struct task_smack *tsp = smack_cred(current_cred());
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
        char acc[SMK_NUM_ACCESS_TYPE + 1];
 
        if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -197,7 +197,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
        struct task_smack *tsp = smack_cred(current_cred());
        struct smack_known *sskp = tsp->smk_task;
        struct inode *inode = file_inode(file);
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
        char acc[SMK_NUM_ACCESS_TYPE + 1];
 
        if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -227,7 +227,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
        struct task_smack *tsp = smack_cred(cred);
        struct smack_known *sskp = tsp->smk_task;
        struct inode *inode = file_inode(file);
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
        char acc[SMK_NUM_ACCESS_TYPE + 1];
 
        if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -287,18 +287,24 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip,
 }
 
 /**
- * init_inode_smack - initialize an inode security blob
- * @isp: the blob to initialize
+ * new_inode_smack - allocate an inode security blob
  * @skp: a pointer to the Smack label entry to use in the blob
  *
+ * Returns the new blob or NULL if there's no memory available
  */
-static void init_inode_smack(struct inode *inode, struct smack_known *skp)
+static struct inode_smack *new_inode_smack(struct smack_known *skp)
 {
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp;
+
+       isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS);
+       if (isp == NULL)
+               return NULL;
 
        isp->smk_inode = skp;
        isp->smk_flags = 0;
        mutex_init(&isp->smk_lock);
+
+       return isp;
 }
 
 /**
@@ -519,7 +525,12 @@ static int smack_syslog(int typefrom_file)
  */
 static int smack_sb_alloc_security(struct super_block *sb)
 {
-       struct superblock_smack *sbsp = smack_superblock(sb);
+       struct superblock_smack *sbsp;
+
+       sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
+
+       if (sbsp == NULL)
+               return -ENOMEM;
 
        sbsp->smk_root = &smack_known_floor;
        sbsp->smk_default = &smack_known_floor;
@@ -528,10 +539,22 @@ static int smack_sb_alloc_security(struct super_block *sb)
        /*
         * SMK_SB_INITIALIZED will be zero from kzalloc.
         */
+       sb->s_security = sbsp;
 
        return 0;
 }
 
+/**
+ * smack_sb_free_security - free a superblock blob
+ * @sb: the superblock getting the blob
+ *
+ */
+static void smack_sb_free_security(struct super_block *sb)
+{
+       kfree(sb->s_security);
+       sb->s_security = NULL;
+}
+
 /**
  * smack_sb_copy_data - copy mount options data for processing
  * @orig: where to start
@@ -722,7 +745,7 @@ static int smack_set_mnt_opts(struct super_block *sb,
 {
        struct dentry *root = sb->s_root;
        struct inode *inode = d_backing_inode(root);
-       struct superblock_smack *sp = smack_superblock(sb);
+       struct superblock_smack *sp = sb->s_security;
        struct inode_smack *isp;
        struct smack_known *skp;
        int i;
@@ -800,13 +823,17 @@ static int smack_set_mnt_opts(struct super_block *sb,
        /*
         * Initialize the root inode.
         */
-       lsm_early_inode(inode);
-       init_inode_smack(inode, sp->smk_root);
+       isp = inode->i_security;
+       if (isp == NULL) {
+               isp = new_inode_smack(sp->smk_root);
+               if (isp == NULL)
+                       return -ENOMEM;
+               inode->i_security = isp;
+       } else
+               isp->smk_inode = sp->smk_root;
 
-       if (transmute) {
-               isp = smack_inode(inode);
+       if (transmute)
                isp->smk_flags |= SMK_INODE_TRANSMUTE;
-       }
 
        return 0;
 }
@@ -851,7 +878,7 @@ out_err:
  */
 static int smack_sb_statfs(struct dentry *dentry)
 {
-       struct superblock_smack *sbp = smack_superblock(dentry->d_sb);
+       struct superblock_smack *sbp = dentry->d_sb->s_security;
        int rc;
        struct smk_audit_info ad;
 
@@ -884,11 +911,11 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
        if (bprm->cred_prepared)
                return 0;
 
-       isp = smack_inode(inode);
+       isp = inode->i_security;
        if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
                return 0;
 
-       sbsp = smack_superblock(inode->i_sb);
+       sbsp = inode->i_sb->s_security;
        if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
            isp->smk_task != sbsp->smk_root)
                return 0;
@@ -961,10 +988,48 @@ static int smack_inode_alloc_security(struct inode *inode)
 {
        struct smack_known *skp = smk_of_current();
 
-       init_inode_smack(inode, skp);
+       inode->i_security = new_inode_smack(skp);
+       if (inode->i_security == NULL)
+               return -ENOMEM;
        return 0;
 }
 
+/**
+ * smack_inode_free_rcu - Free inode_smack blob from cache
+ * @head: the rcu_head for getting inode_smack pointer
+ *
+ *  Call back function called from call_rcu() to free
+ *  the i_security blob pointer in inode
+ */
+static void smack_inode_free_rcu(struct rcu_head *head)
+{
+       struct inode_smack *issp;
+
+       issp = container_of(head, struct inode_smack, smk_rcu);
+       kmem_cache_free(smack_inode_cache, issp);
+}
+
+/**
+ * smack_inode_free_security - free an inode blob using call_rcu()
+ * @inode: the inode with a blob
+ *
+ * Clears the blob pointer in inode using RCU
+ */
+static void smack_inode_free_security(struct inode *inode)
+{
+       struct inode_smack *issp = inode->i_security;
+
+       /*
+        * The inode may still be referenced in a path walk and
+        * a call to smack_inode_permission() can be made
+        * after smack_inode_free_security() is called.
+        * To avoid race condition free the i_security via RCU
+        * and leave the current inode->i_security pointer intact.
+        * The inode will be freed after the RCU grace period too.
+        */
+       call_rcu(&issp->smk_rcu, smack_inode_free_rcu);
+}
+
 /**
  * smack_inode_init_security - copy out the smack from an inode
  * @inode: the newly created inode
@@ -980,7 +1045,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
                                     const struct qstr *qstr, const char **name,
                                     void **value, size_t *len)
 {
-       struct inode_smack *issp = smack_inode(inode);
+       struct inode_smack *issp = inode->i_security;
        struct smack_known *skp = smk_of_current();
        struct smack_known *isp = smk_of_inode(inode);
        struct smack_known *dsp = smk_of_inode(dir);
@@ -1318,7 +1383,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
                                      const void *value, size_t size, int flags)
 {
        struct smack_known *skp;
-       struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
+       struct inode_smack *isp = d_backing_inode(dentry)->i_security;
 
        if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
                isp->smk_flags |= SMK_INODE_TRANSMUTE;
@@ -1399,7 +1464,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
        if (rc != 0)
                return rc;
 
-       isp = smack_inode(d_backing_inode(dentry));
+       isp = d_backing_inode(dentry)->i_security;
        /*
         * Don't do anything special for these.
         *      XATTR_NAME_SMACKIPIN
@@ -1453,7 +1518,7 @@ static int smack_inode_getsecurity(struct inode *inode,
                if (sock == NULL || sock->sk == NULL)
                        return -EOPNOTSUPP;
 
-               ssp = smack_sock(sock->sk);
+               ssp = sock->sk->sk_security;
 
                if (strcmp(name, XATTR_SMACK_IPIN) == 0)
                        isp = ssp->smk_in;
@@ -1497,7 +1562,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  */
 static void smack_inode_getsecid(struct inode *inode, u32 *secid)
 {
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
 
        *secid = isp->smk_inode->smk_secid;
 }
@@ -1674,7 +1739,7 @@ static int smack_mmap_file(struct file *file,
        if (unlikely(IS_PRIVATE(file_inode(file))))
                return 0;
 
-       isp = smack_inode(file_inode(file));
+       isp = file_inode(file)->i_security;
        if (isp->smk_mmap == NULL)
                return 0;
        sbsp = file_inode(file)->i_sb->s_security;
@@ -1830,7 +1895,7 @@ static int smack_file_receive(struct file *file)
 
        if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
                sock = SOCKET_I(inode);
-               ssp = smack_sock(sock->sk);
+               ssp = sock->sk->sk_security;
                tsp = smack_cred(current_cred());
                /*
                 * If the receiving process can't write to the
@@ -1999,7 +2064,7 @@ static int smack_kernel_act_as(struct cred *new, u32 secid)
 static int smack_kernel_create_files_as(struct cred *new,
                                        struct inode *inode)
 {
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
        struct task_smack *tsp = smack_cred(new);
 
        tsp->smk_forked = isp->smk_inode;
@@ -2201,7 +2266,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
  */
 static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
 {
-       struct inode_smack *isp = smack_inode(inode);
+       struct inode_smack *isp = inode->i_security;
        struct smack_known *skp = smk_of_task_struct(p);
 
        isp->smk_inode = skp;
@@ -2224,7 +2289,11 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
 static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
 {
        struct smack_known *skp = smk_of_current();
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp;
+
+       ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
+       if (ssp == NULL)
+               return -ENOMEM;
 
        /*
         * Sockets created by kernel threads receive web label.
@@ -2238,10 +2307,11 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
        }
        ssp->smk_packet = NULL;
 
+       sk->sk_security = ssp;
+
        return 0;
 }
 
-#ifdef SMACK_IPV6_PORT_LABELING
 /**
  * smack_sk_free_security - Free a socket blob
  * @sk: the socket
@@ -2250,6 +2320,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
  */
 static void smack_sk_free_security(struct sock *sk)
 {
+#ifdef SMACK_IPV6_PORT_LABELING
        struct smk_port_label *spp;
 
        if (sk->sk_family == PF_INET6) {
@@ -2262,8 +2333,9 @@ static void smack_sk_free_security(struct sock *sk)
                }
                rcu_read_unlock();
        }
-}
 #endif
+       kfree(sk->sk_security);
+}
 
 /**
 * smack_ipv4host_label - check host based restrictions
@@ -2381,7 +2453,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
 static int smack_netlabel(struct sock *sk, int labeled)
 {
        struct smack_known *skp;
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        int rc = 0;
 
        /*
@@ -2426,7 +2498,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
        int rc;
        int sk_lbl;
        struct smack_known *hkp;
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        struct smk_audit_info ad;
 
        rcu_read_lock();
@@ -2502,7 +2574,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
 {
        struct sock *sk = sock->sk;
        struct sockaddr_in6 *addr6;
-       struct socket_smack *ssp = smack_sock(sock->sk);
+       struct socket_smack *ssp = sock->sk->sk_security;
        struct smk_port_label *spp;
        unsigned short port = 0;
 
@@ -2589,7 +2661,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
                                int act)
 {
        struct smk_port_label *spp;
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp = NULL;
        unsigned short port;
        struct smack_known *object;
@@ -2656,7 +2728,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
                                   const void *value, size_t size, int flags)
 {
        struct smack_known *skp;
-       struct inode_smack *nsp = smack_inode(inode);
+       struct inode_smack *nsp = inode->i_security;
        struct socket_smack *ssp;
        struct socket *sock;
        int rc = 0;
@@ -2683,7 +2755,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
        if (sock == NULL || sock->sk == NULL)
                return -EOPNOTSUPP;
 
-       ssp = smack_sock(sock->sk);
+       ssp = sock->sk->sk_security;
 
        if (strcmp(name, XATTR_SMACK_IPIN) == 0)
                ssp->smk_in = skp;
@@ -2731,7 +2803,7 @@ static int smack_socket_post_create(struct socket *sock, int family,
         * Sockets created by kernel threads receive web label.
         */
        if (unlikely(current->flags & PF_KTHREAD)) {
-               ssp = smack_sock(sock->sk);
+               ssp = sock->sk->sk_security;
                ssp->smk_in = &smack_known_web;
                ssp->smk_out = &smack_known_web;
        }
@@ -2783,7 +2855,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
 #endif
 #ifdef SMACK_IPV6_SECMARK_LABELING
        struct smack_known *rsp;
-       struct socket_smack *ssp = smack_sock(sock->sk);
+       struct socket_smack *ssp = sock->sk->sk_security;
 #endif
 
        if (sock->sk == NULL)
@@ -2840,12 +2912,34 @@ static int smack_flags_to_may(int flags)
  */
 static int smack_msg_msg_alloc_security(struct msg_msg *msg)
 {
-       struct smack_known **blob = smack_msg_msg(msg);
+       struct smack_known *skp = smk_of_current();
 
-       *blob = smk_of_current();
+       msg->security = skp;
        return 0;
 }
 
+/**
+ * smack_msg_msg_free_security - Clear the security blob for msg_msg
+ * @msg: the object
+ *
+ * Clears the blob pointer
+ */
+static void smack_msg_msg_free_security(struct msg_msg *msg)
+{
+       msg->security = NULL;
+}
+
+/**
+ * smack_of_shm - the smack pointer for the shm
+ * @shp: the object
+ *
+ * Returns a pointer to the smack value
+ */
+static struct smack_known *smack_of_shm(struct shmid_kernel *shp)
+{
+       return (struct smack_known *)shp->shm_perm.security;
+}
+
 /**
  * smack_shm_alloc_security - Set the security blob for shm
  * @shp: the object
@@ -2854,12 +2948,26 @@ static int smack_msg_msg_alloc_security(struct msg_msg *msg)
  */
 static int smack_shm_alloc_security(struct shmid_kernel *shp)
 {
-       struct smack_known **blob = smack_ipc(&shp->shm_perm);
+       struct kern_ipc_perm *isp = &shp->shm_perm;
+       struct smack_known *skp = smk_of_current();
 
-       *blob = smk_of_current();
+       isp->security = skp;
        return 0;
 }
 
+/**
+ * smack_shm_free_security - Clear the security blob for shm
+ * @shp: the object
+ *
+ * Clears the blob pointer
+ */
+static void smack_shm_free_security(struct shmid_kernel *shp)
+{
+       struct kern_ipc_perm *isp = &shp->shm_perm;
+
+       isp->security = NULL;
+}
+
 /**
  * smk_curacc_shm : check if current has access on shm
  * @shp : the object
@@ -2869,8 +2977,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp)
  */
 static int smk_curacc_shm(struct shmid_kernel *shp, int access)
 {
-       struct smack_known **blob = smack_ipc(&shp->shm_perm);
-       struct smack_known *ssp = *blob;
+       struct smack_known *ssp = smack_of_shm(shp);
        struct smk_audit_info ad;
        int rc;
 
@@ -2949,6 +3056,17 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
        return smk_curacc_shm(shp, may);
 }
 
+/**
+ * smack_of_sem - the smack pointer for the sem
+ * @sma: the object
+ *
+ * Returns a pointer to the smack value
+ */
+static struct smack_known *smack_of_sem(struct sem_array *sma)
+{
+       return (struct smack_known *)sma->sem_perm.security;
+}
+
 /**
  * smack_sem_alloc_security - Set the security blob for sem
  * @sma: the object
@@ -2957,12 +3075,26 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
  */
 static int smack_sem_alloc_security(struct sem_array *sma)
 {
-       struct smack_known **blob = smack_ipc(&sma->sem_perm);
+       struct kern_ipc_perm *isp = &sma->sem_perm;
+       struct smack_known *skp = smk_of_current();
 
-       *blob = smk_of_current();
+       isp->security = skp;
        return 0;
 }
 
+/**
+ * smack_sem_free_security - Clear the security blob for sem
+ * @sma: the object
+ *
+ * Clears the blob pointer
+ */
+static void smack_sem_free_security(struct sem_array *sma)
+{
+       struct kern_ipc_perm *isp = &sma->sem_perm;
+
+       isp->security = NULL;
+}
+
 /**
  * smk_curacc_sem : check if current has access on sem
  * @sma : the object
@@ -2972,8 +3104,7 @@ static int smack_sem_alloc_security(struct sem_array *sma)
  */
 static int smk_curacc_sem(struct sem_array *sma, int access)
 {
-       struct smack_known **blob = smack_ipc(&sma->sem_perm);
-       struct smack_known *ssp = *blob;
+       struct smack_known *ssp = smack_of_sem(sma);
        struct smk_audit_info ad;
        int rc;
 
@@ -3059,19 +3190,44 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
 }
 
 /**
- * smack_msg_queue_alloc_security - Set the security blob for msg
+ * smack_msg_alloc_security - Set the security blob for msg
  * @msq: the object
  *
  * Returns 0
  */
 static int smack_msg_queue_alloc_security(struct msg_queue *msq)
 {
-       struct smack_known **blob = smack_ipc(&msq->q_perm);
+       struct kern_ipc_perm *kisp = &msq->q_perm;
+       struct smack_known *skp = smk_of_current();
 
-       *blob = smk_of_current();
+       kisp->security = skp;
        return 0;
 }
 
+/**
+ * smack_msg_free_security - Clear the security blob for msg
+ * @msq: the object
+ *
+ * Clears the blob pointer
+ */
+static void smack_msg_queue_free_security(struct msg_queue *msq)
+{
+       struct kern_ipc_perm *kisp = &msq->q_perm;
+
+       kisp->security = NULL;
+}
+
+/**
+ * smack_of_msq - the smack pointer for the msq
+ * @msq: the object
+ *
+ * Returns a pointer to the smack label entry
+ */
+static struct smack_known *smack_of_msq(struct msg_queue *msq)
+{
+       return (struct smack_known *)msq->q_perm.security;
+}
+
 /**
  * smk_curacc_msq : helper to check if current has access on msq
  * @msq : the msq
@@ -3081,8 +3237,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
  */
 static int smk_curacc_msq(struct msg_queue *msq, int access)
 {
-       struct smack_known **blob = smack_ipc(&msq->q_perm);
-       struct smack_known *msp = *blob;
+       struct smack_known *msp = smack_of_msq(msq);
        struct smk_audit_info ad;
        int rc;
 
@@ -3185,8 +3340,7 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
  */
 static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
 {
-       struct smack_known **blob = smack_ipc(ipp);
-       struct smack_known *iskp = *blob;
+       struct smack_known *iskp = ipp->security;
        int may = smack_flags_to_may(flag);
        struct smk_audit_info ad;
        int rc;
@@ -3207,8 +3361,7 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
  */
 static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
 {
-       struct smack_known **blob = smack_ipc(ipp);
-       struct smack_known *iskp = *blob;
+       struct smack_known *iskp = ipp->security;
 
        *secid = iskp->smk_secid;
 }
@@ -3236,7 +3389,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
        if (inode == NULL)
                return;
 
-       isp = smack_inode(inode);
+       isp = inode->i_security;
 
        mutex_lock(&isp->smk_lock);
        /*
@@ -3247,7 +3400,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
                goto unlockandout;
 
        sbp = inode->i_sb;
-       sbsp = smack_superblock(sbp);
+       sbsp = sbp->s_security;
        /*
         * We're going to use the superblock default label
         * if there's no label on the file.
@@ -3543,9 +3696,9 @@ static int smack_unix_stream_connect(struct sock *sock,
 {
        struct smack_known *skp;
        struct smack_known *okp;
-       struct socket_smack *ssp = smack_sock(sock);
-       struct socket_smack *osp = smack_sock(other);
-       struct socket_smack *nsp = smack_sock(newsk);
+       struct socket_smack *ssp = sock->sk_security;
+       struct socket_smack *osp = other->sk_security;
+       struct socket_smack *nsp = newsk->sk_security;
        struct smk_audit_info ad;
        int rc = 0;
 #ifdef CONFIG_AUDIT
@@ -3591,8 +3744,8 @@ static int smack_unix_stream_connect(struct sock *sock,
  */
 static int smack_unix_may_send(struct socket *sock, struct socket *other)
 {
-       struct socket_smack *ssp = smack_sock(sock->sk);
-       struct socket_smack *osp = smack_sock(other->sk);
+       struct socket_smack *ssp = sock->sk->sk_security;
+       struct socket_smack *osp = other->sk->sk_security;
        struct smk_audit_info ad;
        int rc;
 
@@ -3629,7 +3782,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
        struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
 #endif
 #ifdef SMACK_IPV6_SECMARK_LABELING
-       struct socket_smack *ssp = smack_sock(sock->sk);
+       struct socket_smack *ssp = sock->sk->sk_security;
        struct smack_known *rsp;
 #endif
        int rc = 0;
@@ -3793,7 +3946,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
 static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        struct netlbl_lsm_secattr secattr;
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp = NULL;
        int rc = 0;
        struct smk_audit_info ad;
@@ -3902,7 +4055,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
        int slen = 1;
        int rc = 0;
 
-       ssp = smack_sock(sock->sk);
+       ssp = sock->sk->sk_security;
        if (ssp->smk_packet != NULL) {
                rcp = ssp->smk_packet->smk_known;
                slen = strlen(rcp) + 1;
@@ -3952,7 +4105,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
 
        switch (family) {
        case PF_UNIX:
-               ssp = smack_sock(sock->sk);
+               ssp = sock->sk->sk_security;
                s = ssp->smk_out->smk_secid;
                break;
        case PF_INET:
@@ -3965,7 +4118,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
                 * Translate what netlabel gave us.
                 */
                if (sock != NULL && sock->sk != NULL)
-                       ssp = smack_sock(sock->sk);
+                       ssp = sock->sk->sk_security;
                netlbl_secattr_init(&secattr);
                rc = netlbl_skbuff_getattr(skb, family, &secattr);
                if (rc == 0) {
@@ -4003,7 +4156,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
            (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
                return;
 
-       ssp = smack_sock(sk);
+       ssp = sk->sk_security;
        ssp->smk_in = skp;
        ssp->smk_out = skp;
        /* cssp->smk_packet is already set in smack_inet_csk_clone() */
@@ -4023,7 +4176,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 {
        u16 family = sk->sk_family;
        struct smack_known *skp;
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        struct netlbl_lsm_secattr secattr;
        struct sockaddr_in addr;
        struct iphdr *hdr;
@@ -4122,7 +4275,7 @@ access_check:
 static void smack_inet_csk_clone(struct sock *sk,
                                 const struct request_sock *req)
 {
-       struct socket_smack *ssp = smack_sock(sk);
+       struct socket_smack *ssp = sk->sk_security;
        struct smack_known *skp;
 
        if (req->peer_secid != 0) {
@@ -4154,13 +4307,23 @@ static void smack_inet_csk_clone(struct sock *sk,
 static int smack_key_alloc(struct key *key, const struct cred *cred,
                           unsigned long flags)
 {
-       struct smack_known **blob = smack_key(key);
        struct smack_known *skp = smk_of_task(smack_cred(cred));
 
-       *blob = skp;
+       key->security = skp;
        return 0;
 }
 
+/**
+ * smack_key_free - Clear the key security blob
+ * @key: the object
+ *
+ * Clear the blob pointer
+ */
+static void smack_key_free(struct key *key)
+{
+       key->security = NULL;
+}
+
 /**
  * smack_key_permission - Smack access on a key
  * @key_ref: gets to the object
@@ -4173,8 +4336,6 @@ static int smack_key_alloc(struct key *key, const struct cred *cred,
 static int smack_key_permission(key_ref_t key_ref,
                                const struct cred *cred, unsigned perm)
 {
-       struct smack_known **blob;
-       struct smack_known *skp;
        struct key *keyp;
        struct smk_audit_info ad;
        struct smack_known *tkp = smk_of_task(smack_cred(cred));
@@ -4188,9 +4349,7 @@ static int smack_key_permission(key_ref_t key_ref,
         * If the key hasn't been initialized give it access so that
         * it may do so.
         */
-       blob = smack_key(keyp);
-       skp = *blob;
-       if (skp == NULL)
+       if (keyp->security == NULL)
                return 0;
        /*
         * This should not occur
@@ -4206,8 +4365,8 @@ static int smack_key_permission(key_ref_t key_ref,
                request = MAY_READ;
        if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
                request = MAY_WRITE;
-       rc = smk_access(tkp, skp, request, &ad);
-       rc = smk_bu_note("key access", tkp, skp, request, rc);
+       rc = smk_access(tkp, keyp->security, request, &ad);
+       rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
        return rc;
 }
 
@@ -4222,12 +4381,11 @@ static int smack_key_permission(key_ref_t key_ref,
  */
 static int smack_key_getsecurity(struct key *key, char **_buffer)
 {
-       struct smack_known **blob = smack_key(key);
-       struct smack_known *skp = *blob;
+       struct smack_known *skp = key->security;
        size_t length;
        char *copy;
 
-       if (skp == NULL) {
+       if (key->security == NULL) {
                *_buffer = NULL;
                return 0;
        }
@@ -4436,14 +4594,6 @@ static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
 struct lsm_blob_sizes smack_blob_sizes = {
        .lbs_cred = sizeof(struct task_smack),
        .lbs_file = sizeof(struct smack_known *),
-       .lbs_inode = sizeof(struct inode_smack),
-       .lbs_ipc = sizeof(struct smack_known *),
-#ifdef CONFIG_KEYS
-       .lbs_key = sizeof(struct smack_known *),
-#endif /* CONFIG_KEYS */
-       .lbs_msg_msg = sizeof(struct smack_known *),
-       .lbs_sock = sizeof(struct socket_smack),
-       .lbs_superblock = sizeof(struct superblock_smack),
 };
 
 static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
@@ -4452,6 +4602,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(syslog, smack_syslog),
 
        LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
+       LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
        LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
        LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
        LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
@@ -4463,6 +4614,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec),
 
        LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
+       LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
        LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
        LSM_HOOK_INIT(inode_link, smack_inode_link),
        LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
@@ -4515,19 +4667,23 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
 
        LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
+       LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security),
 
        LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security),
+       LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security),
        LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
        LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
        LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
        LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
 
        LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security),
+       LSM_HOOK_INIT(shm_free_security, smack_shm_free_security),
        LSM_HOOK_INIT(shm_associate, smack_shm_associate),
        LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
        LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
 
        LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security),
+       LSM_HOOK_INIT(sem_free_security, smack_sem_free_security),
        LSM_HOOK_INIT(sem_associate, smack_sem_associate),
        LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
        LSM_HOOK_INIT(sem_semop, smack_sem_semop),
@@ -4550,9 +4706,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream),
        LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram),
        LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
-#ifdef SMACK_IPV6_PORT_LABELING
        LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
-#endif
        LSM_HOOK_INIT(sock_graft, smack_sock_graft),
        LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
        LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
@@ -4560,6 +4714,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
  /* key management security hooks */
 #ifdef CONFIG_KEYS
        LSM_HOOK_INIT(key_alloc, smack_key_alloc),
+       LSM_HOOK_INIT(key_free, smack_key_free),
        LSM_HOOK_INIT(key_permission, smack_key_permission),
        LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
 #endif /* CONFIG_KEYS */
index a5155295551f5e72802ab6d50ff87c01a6ed417b..cdeb0f3243dd635ced5e9efb49fb3fb61d37e4f3 100644 (file)
@@ -31,8 +31,8 @@ static unsigned int smack_ipv6_output(void *priv,
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (sk && smack_sock(sk)) {
-               ssp = smack_sock(sk);
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }
@@ -49,8 +49,8 @@ static unsigned int smack_ipv4_output(void *priv,
        struct socket_smack *ssp;
        struct smack_known *skp;
 
-       if (sk && smack_sock(sk)) {
-               ssp = smack_sock(sk);
+       if (sk && sk->sk_security) {
+               ssp = sk->sk_security;
                skp = ssp->smk_out;
                skb->secmark = skp->smk_secid;
        }