diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 9cc0e49..c03d339 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1851,6 +1851,7 @@ struct lsm_blob_sizes {
 	int	lbs_cred;
 	int	lbs_file;
 	int	lbs_inode;
+	int	lbs_sock;
 };
 
 /*
diff --git a/security/security.c b/security/security.c
index 9fc5967..b728624 100644
--- a/security/security.c
+++ b/security/security.c
@@ -26,6 +26,7 @@
 #include <linux/personality.h>
 #include <linux/backing-dev.h>
 #include <net/flow.h>
+#include <net/sock.h>
 
 #define MAX_LSM_EVM_XATTR	2
 
@@ -87,6 +88,7 @@ int __init security_init(void)
 	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: sock blob size       = %d\n", blob_sizes.lbs_sock);
 #endif
 
 	return 0;
@@ -227,6 +229,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_inode, &blob_sizes.lbs_inode);
+	lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
 }
 
 /**
@@ -279,6 +282,31 @@ int lsm_inode_alloc(struct inode *inode)
 	return 0;
 }
 
+/**
+ * lsm_sock_alloc - allocate a composite sock blob
+ * @sock: the sock that needs a blob
+ *
+ * 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)
+{
+#ifdef CONFIG_SECURITY_STACKING_DEBUG
+	if (sock->sk_security) {
+		pr_info("%s: Inbound sock blob is not NULL.\n", __func__);
+		return 0;
+	}
+#endif
+	if (blob_sizes.lbs_sock == 0)
+		return 0;
+
+	sock->sk_security = kzalloc(blob_sizes.lbs_sock, GFP_KERNEL);
+	if (sock->sk_security == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
 /*
  * Hook list operation macros.
  *
@@ -1645,12 +1673,18 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram);
 
 int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
 {
+	int rc = lsm_sock_alloc(sk);
+
+	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)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7219a6a..f930c9f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4639,17 +4639,12 @@ out:
 
 static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
-	struct sk_security_struct *sksec;
-
-	sksec = kzalloc(sizeof(*sksec), priority);
-	if (!sksec)
-		return -ENOMEM;
+	struct sk_security_struct *sksec = selinux_sock(sk);
 
 	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;
 }
@@ -4658,9 +4653,7 @@ static void selinux_sk_free_security(struct sock *sk)
 {
 	struct sk_security_struct *sksec = selinux_sock(sk);
 
-	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)
@@ -5966,6 +5959,7 @@ 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_sock = sizeof(struct sk_security_struct),
 };
 
 static struct security_hook_list selinux_hooks[] = {
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 7f5f4b8..f2820a8 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -183,7 +183,11 @@ static inline struct key_security_struct *selinux_key(const struct key *key)
 
 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_ */
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 141f3bf..d377efe 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -370,7 +370,11 @@ static inline struct inode_smack *smack_inode(const struct inode *inode)
 
 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(
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 6dea0a7..c8e4d02 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1859,7 +1859,7 @@ static int smack_file_receive(struct file *file)
 
 	if (S_ISSOCK(inode->i_mode)) {
 		sock = SOCKET_I(inode);
-		ssp = sock->sk->sk_security;
+		ssp = smack_sock(sock->sk);
 		tsp = smack_cred(current_cred());
 		/*
 		 * If the receiving process can't write to the
@@ -2279,35 +2279,16 @@ 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;
-
-	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
-	if (ssp == NULL)
-		return -ENOMEM;
+	struct socket_smack *ssp = smack_sock(sk);
 
 	ssp->smk_in = skp;
 	ssp->smk_out = skp;
 	ssp->smk_packet = NULL;
 
-	sk->sk_security = ssp;
-
 	return 0;
 }
 
 /**
- * smack_sk_free_security - Free a socket blob
- * @sk: the socket
- *
- * Clears the blob pointer
- */
-static void smack_sk_free_security(struct sock *sk)
-{
-	struct socket_smack *ssp = smack_sock(sk);
-
-	kfree(ssp);
-}
-
-/**
 * smack_ipv4host_label - check host based restrictions
 * @sip: the object end
 *
@@ -4569,6 +4550,7 @@ 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_sock = sizeof(struct socket_smack),
 };
 
 static struct security_hook_list smack_hooks[] = {
@@ -4681,7 +4663,6 @@ static struct security_hook_list smack_hooks[] = {
 	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),
-	LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
 	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),
