Thread (36 messages) 36 messages, 7 authors, 2018-10-09
STALE2788d

[PATCH v1 18/22] LSM: Use multiple secids in security module interfaces

From: casey@schaufler-ca.com (Casey Schaufler)
Date: 2018-07-16 18:24:38
Also in: lkml, selinux
Subsystem: apparmor security module, bpf [general] (safe dynamic programs and tools), bpf [networking] (tcx & tc bpf, sock_addr), networking [general], networking [ipsec], networking [labeled] (netlabel, labeled ipsec, secmark), security subsystem, selinux security module, smack security module, the rest · Maintainers: John Johansen, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Steffen Klassert, Herbert Xu, Paul Moore, James Morris, "Serge E. Hallyn", Stephen Smalley, Casey Schaufler, Linus Torvalds

LSM: Use multiple secids in security module interfaces

This is the first of two parts required to change the
security module infrastructure from using a u32 to
identify extended security attributes to using a pointer
to a structure containing the information required for
the set of security modules involved. You can't put an
SELinux secid, a Smack secid and an AppArmor secid
all into a u32. They don't fit. Schemes that map a
single u32 into sets of u32s are frought with data
management issues and as a result are not suitable for
use in the variety of ways secids manifest themselves
in the Linux kernel.

This patch changes the interfaces to the security modules
to use a "struct secids" pointer where they used a u32
before. There are changes in networking code where the
layering isn't so clean as I would like it to be.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/lsm_hooks.h         | 38 +++++++-------
 include/linux/security.h          | 19 +++++++
 include/net/flow.h                |  5 +-
 include/net/netlabel.h            |  8 +--
 net/core/filter.c                 |  4 +-
 net/ipv4/cipso_ipv4.c             |  4 +-
 net/netlabel/netlabel_kapi.c      |  4 +-
 net/netlabel/netlabel_unlabeled.c | 29 ++++++-----
 net/netlabel/netlabel_user.c      |  4 +-
 net/netlabel/netlabel_user.h      |  2 +-
 net/xfrm/xfrm_policy.c            |  7 +--
 net/xfrm/xfrm_state.c             |  3 +-
 security/apparmor/audit.c         |  4 +-
 security/apparmor/include/audit.h |  2 +-
 security/apparmor/include/secid.h |  5 +-
 security/apparmor/lsm.c           |  7 +--
 security/apparmor/secid.c         |  9 ++--
 security/security.c               | 85 ++++++++++++++++++++++++-------
 security/selinux/hooks.c          | 59 +++++++++++----------
 security/selinux/include/audit.h  |  2 +-
 security/selinux/include/xfrm.h   |  9 ++--
 security/selinux/netlabel.c       |  2 +-
 security/selinux/ss/services.c    | 10 ++--
 security/selinux/xfrm.c           | 25 +++++----
 security/smack/smack_access.c     |  4 +-
 security/smack/smack_lsm.c        | 76 +++++++++++++++------------
 security/smack/smackfs.c          | 14 +++--
 27 files changed, 275 insertions(+), 165 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 115e7cd89d88..7c321d11d994 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1548,7 +1548,7 @@ union security_list_options {
 					int flags);
 	int (*inode_listsecurity)(struct inode *inode, char *buffer,
 					size_t buffer_size);
-	void (*inode_getsecid)(struct inode *inode, u32 *secid);
+	void (*inode_getsecid)(struct inode *inode, struct secids *secid);
 	int (*inode_copy_up)(struct dentry *src, struct cred **new);
 	int (*inode_copy_up_xattr)(const char *name);
 
@@ -1578,8 +1578,8 @@ union security_list_options {
 	int (*cred_prepare)(struct cred *new, const struct cred *old,
 				gfp_t gfp);
 	void (*cred_transfer)(struct cred *new, const struct cred *old);
-	void (*cred_getsecid)(const struct cred *c, u32 *secid);
-	int (*kernel_act_as)(struct cred *new, u32 secid);
+	void (*cred_getsecid)(const struct cred *c, struct secids *secid);
+	int (*kernel_act_as)(struct cred *new, struct secids *secid);
 	int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
 	int (*kernel_module_request)(char *kmod_name);
 	int (*kernel_read_file)(struct file *file, enum kernel_read_file_id id);
@@ -1590,7 +1590,7 @@ union security_list_options {
 	int (*task_setpgid)(struct task_struct *p, pid_t pgid);
 	int (*task_getpgid)(struct task_struct *p);
 	int (*task_getsid)(struct task_struct *p);
-	void (*task_getsecid)(struct task_struct *p, u32 *secid);
+	void (*task_getsecid)(struct task_struct *p, struct secids *secid);
 	int (*task_setnice)(struct task_struct *p, int nice);
 	int (*task_setioprio)(struct task_struct *p, int ioprio);
 	int (*task_getioprio)(struct task_struct *p);
@@ -1608,7 +1608,7 @@ union security_list_options {
 	void (*task_to_inode)(struct task_struct *p, struct inode *inode);
 
 	int (*ipc_permission)(struct kern_ipc_perm *ipcp, short flag);
-	void (*ipc_getsecid)(struct kern_ipc_perm *ipcp, u32 *secid);
+	void (*ipc_getsecid)(struct kern_ipc_perm *ipcp, struct secids *secid);
 
 	int (*msg_msg_alloc_security)(struct msg_msg *msg);
 	void (*msg_msg_free_security)(struct msg_msg *msg);
@@ -1644,8 +1644,10 @@ union security_list_options {
 	int (*getprocattr)(struct task_struct *p, char *name, char **value);
 	int (*setprocattr)(const char *name, void *value, size_t size);
 	int (*ismaclabel)(const char *name);
-	int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
-	int (*secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid);
+	int (*secid_to_secctx)(struct secids *secid, char **secdata,
+				u32 *seclen);
+	int (*secctx_to_secid)(const char *secdata, u32 seclen,
+				struct secids *secid);
 	void (*release_secctx)(char *secdata, u32 seclen);
 
 	void (*inode_invalidate_secctx)(struct inode *inode);
@@ -1680,20 +1682,21 @@ union security_list_options {
 	int (*socket_sock_rcv_skb)(struct sock *sk, struct sk_buff *skb);
 	int (*socket_getpeersec_stream)(struct socket *sock,
 					char __user *optval,
-					int __user *optlen, unsigned len);
+					int __user *optlen, unsigned int len);
 	int (*socket_getpeersec_dgram)(struct socket *sock,
-					struct sk_buff *skb, u32 *secid);
+					struct sk_buff *skb,
+					struct secids *secid);
 	int (*sk_alloc_security)(struct sock *sk, int family, gfp_t priority);
 	void (*sk_free_security)(struct sock *sk);
 	void (*sk_clone_security)(const struct sock *sk, struct sock *newsk);
-	void (*sk_getsecid)(struct sock *sk, u32 *secid);
+	void (*sk_getsecid)(struct sock *sk, struct secids *secid);
 	void (*sock_graft)(struct sock *sk, struct socket *parent);
 	int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb,
 					struct request_sock *req);
 	void (*inet_csk_clone)(struct sock *newsk,
 				const struct request_sock *req);
 	void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb);
-	int (*secmark_relabel_packet)(u32 secid);
+	int (*secmark_relabel_packet)(struct secids *secid);
 	void (*secmark_refcount_inc)(void);
 	void (*secmark_refcount_dec)(void);
 	void (*req_classify_flow)(const struct request_sock *req,
@@ -1732,15 +1735,16 @@ union security_list_options {
 				struct xfrm_user_sec_ctx *sec_ctx);
 	int (*xfrm_state_alloc_acquire)(struct xfrm_state *x,
 					struct xfrm_sec_ctx *polsec,
-					u32 secid);
+					const struct secids *secid);
 	void (*xfrm_state_free_security)(struct xfrm_state *x);
 	int (*xfrm_state_delete_security)(struct xfrm_state *x);
-	int (*xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx, u32 fl_secid,
-					u8 dir);
+	int (*xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx,
+					struct secids *fl_secid, u8 dir);
 	int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,
 						struct xfrm_policy *xp,
 						const struct flowi *fl);
-	int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
+	int (*xfrm_decode_session)(struct sk_buff *skb, struct secids *secid,
+					int ckall);
 #endif	/* CONFIG_SECURITY_NETWORK_XFRM */
 
 	/* key management security hooks */
@@ -1757,8 +1761,8 @@ union security_list_options {
 	int (*audit_rule_init)(u32 field, u32 op, char *rulestr,
 				void **lsmrule);
 	int (*audit_rule_known)(struct audit_krule *krule);
-	int (*audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule,
-				struct audit_context *actx);
+	int (*audit_rule_match)(struct secids *secid, u32 field, u32 op,
+				void *lsmrule, struct audit_context *actx);
 	void (*audit_rule_free)(void *lsmrule);
 #endif /* CONFIG_AUDIT */
 
diff --git a/include/linux/security.h b/include/linux/security.h
index ea875e761d14..6e8e98237a79 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -70,6 +70,25 @@ enum lsm_event {
 	LSM_POLICY_CHANGE,
 };
 
+struct secids {
+	union {
+		u32 common;
+		u32 selinux;
+		u32 smack;
+		u32 apparmor;
+	};
+};
+
+static inline bool secid_valid(const struct secids *secids)
+{
+	return secids->common != 0;
+}
+
+static inline void secid_init(struct secids *secid)
+{
+	memset(secid, 0, sizeof(*secid));
+}
+
 /* These functions are in security/commoncap.c */
 extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
 		       int cap, int audit);
diff --git a/include/net/flow.h b/include/net/flow.h
index 8ce21793094e..aa29d11bc3d7 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -11,6 +11,7 @@
 #include <linux/socket.h>
 #include <linux/in6.h>
 #include <linux/atomic.h>
+#include <linux/security.h>
 #include <net/flow_dissector.h>
 #include <linux/uidgid.h>
 
@@ -37,7 +38,7 @@ struct flowi_common {
 #define FLOWI_FLAG_ANYSRC		0x01
 #define FLOWI_FLAG_KNOWN_NH		0x02
 #define FLOWI_FLAG_SKIP_NH_OIF		0x04
-	__u32	flowic_secid;
+	struct secids flowic_secid;
 	struct flowi_tunnel flowic_tun_key;
 	kuid_t  flowic_uid;
 };
@@ -107,7 +108,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
 	fl4->flowi4_scope = scope;
 	fl4->flowi4_proto = proto;
 	fl4->flowi4_flags = flags;
-	fl4->flowi4_secid = 0;
+	secid_init(&fl4->flowi4_secid);
 	fl4->flowi4_tun_key.tun_id = 0;
 	fl4->flowi4_uid = uid;
 	fl4->daddr = daddr;
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 72d6435fc16c..51dacbb88886 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -111,7 +111,7 @@ struct calipso_doi;
 
 /* NetLabel audit information */
 struct netlbl_audit {
-	u32 secid;
+	struct secids secid;
 	kuid_t loginuid;
 	unsigned int sessionid;
 };
@@ -215,7 +215,7 @@ struct netlbl_lsm_secattr {
 			struct netlbl_lsm_catmap *cat;
 			u32 lvl;
 		} mls;
-		u32 secid;
+		struct secids secid;
 	} attr;
 };
 
@@ -429,7 +429,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
 				const void *addr,
 				const void *mask,
 				u16 family,
-				u32 secid,
+				struct secids *secid,
 				struct netlbl_audit *audit_info);
 int netlbl_cfg_unlbl_static_del(struct net *net,
 				const char *dev_name,
@@ -537,7 +537,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net,
 					      const void *addr,
 					      const void *mask,
 					      u16 family,
-					      u32 secid,
+					      struct secids *secid,
 					      struct netlbl_audit *audit_info)
 {
 	return -ENOSYS;
diff --git a/net/core/filter.c b/net/core/filter.c
index e7f12e9f598c..74cf4c829068 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -4128,7 +4128,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
 		err = fib_table_lookup(tb, &fl4, &res, FIB_LOOKUP_NOREF);
 	} else {
 		fl4.flowi4_mark = 0;
-		fl4.flowi4_secid = 0;
+		secid_init(&fl4.flowi4_secid);
 		fl4.flowi4_tun_key.tun_id = 0;
 		fl4.flowi4_uid = sock_net_uid(net, NULL);
 
@@ -4230,7 +4230,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
 		f6i = ipv6_stub->fib6_table_lookup(net, tb, oif, &fl6, strict);
 	} else {
 		fl6.flowi6_mark = 0;
-		fl6.flowi6_secid = 0;
+		secid_init(&fl6.flowi6_secid);
 		fl6.flowi6_tun_key.tun_id = 0;
 		fl6.flowi6_uid = sock_net_uid(net, NULL);
 
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 82178cc69c96..e17896a5a947 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1480,7 +1480,7 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def,
 
 	buffer[0] = CIPSO_V4_TAG_LOCAL;
 	buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
-	*(u32 *)&buffer[2] = secattr->attr.secid;
+	*(u32 *)&buffer[2] = secattr->attr.secid.common;
 
 	return CIPSO_V4_TAG_LOC_BLEN;
 }
@@ -1500,7 +1500,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
 				 const unsigned char *tag,
 				 struct netlbl_lsm_secattr *secattr)
 {
-	secattr->attr.secid = *(u32 *)&tag[2];
+	secattr->attr.secid.common = *(u32 *)&tag[2];
 	secattr->flags |= NETLBL_SECATTR_SECID;
 
 	return 0;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index ea7c67050792..592ec7ba8822 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -224,7 +224,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
 				const void *addr,
 				const void *mask,
 				u16 family,
-				u32 secid,
+				struct secids *secid,
 				struct netlbl_audit *audit_info)
 {
 	u32 addr_len;
@@ -244,7 +244,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
 
 	return netlbl_unlhsh_add(net,
 				 dev_name, addr, mask, addr_len,
-				 secid, audit_info);
+				 secid->common, audit_info);
 }
 
 /**
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index c070dfc0190a..92744f4791c4 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -80,7 +80,7 @@ struct netlbl_unlhsh_tbl {
 #define netlbl_unlhsh_addr4_entry(iter) \
 	container_of(iter, struct netlbl_unlhsh_addr4, list)
 struct netlbl_unlhsh_addr4 {
-	u32 secid;
+	struct secids secid;
 
 	struct netlbl_af4list list;
 	struct rcu_head rcu;
@@ -88,7 +88,7 @@ struct netlbl_unlhsh_addr4 {
 #define netlbl_unlhsh_addr6_entry(iter) \
 	container_of(iter, struct netlbl_unlhsh_addr6, list)
 struct netlbl_unlhsh_addr6 {
-	u32 secid;
+	struct secids secid;
 
 	struct netlbl_af6list list;
 	struct rcu_head rcu;
@@ -244,7 +244,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
 static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
 				   const struct in_addr *addr,
 				   const struct in_addr *mask,
-				   u32 secid)
+				   struct secids *secid)
 {
 	int ret_val;
 	struct netlbl_unlhsh_addr4 *entry;
@@ -256,7 +256,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
 	entry->list.addr = addr->s_addr & mask->s_addr;
 	entry->list.mask = mask->s_addr;
 	entry->list.valid = 1;
-	entry->secid = secid;
+	entry->secid = *secid;
 
 	spin_lock(&netlbl_unlhsh_lock);
 	ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
@@ -284,7 +284,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
 static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
 				   const struct in6_addr *addr,
 				   const struct in6_addr *mask,
-				   u32 secid)
+				   struct secids *secid)
 {
 	int ret_val;
 	struct netlbl_unlhsh_addr6 *entry;
@@ -300,7 +300,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
 	entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
 	entry->list.mask = *mask;
 	entry->list.valid = 1;
-	entry->secid = secid;
+	entry->secid = *secid;
 
 	spin_lock(&netlbl_unlhsh_lock);
 	ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
@@ -389,6 +389,7 @@ int netlbl_unlhsh_add(struct net *net,
 	struct audit_buffer *audit_buf = NULL;
 	char *secctx = NULL;
 	u32 secctx_len;
+	struct secids ids;
 
 	if (addr_len != sizeof(struct in_addr) &&
 	    addr_len != sizeof(struct in6_addr))
@@ -421,7 +422,8 @@ int netlbl_unlhsh_add(struct net *net,
 		const struct in_addr *addr4 = addr;
 		const struct in_addr *mask4 = mask;
 
-		ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
+		ids.common = secid;
+		ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, &ids);
 		if (audit_buf != NULL)
 			netlbl_af4list_audit_addr(audit_buf, 1,
 						  dev_name,
@@ -434,7 +436,8 @@ int netlbl_unlhsh_add(struct net *net,
 		const struct in6_addr *addr6 = addr;
 		const struct in6_addr *mask6 = mask;
 
-		ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
+		ids.common = secid;
+		ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, &ids);
 		if (audit_buf != NULL)
 			netlbl_af6list_audit_addr(audit_buf, 1,
 						  dev_name,
@@ -508,7 +511,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
 		if (dev != NULL)
 			dev_put(dev);
 		if (entry != NULL &&
-		    security_secid_to_secctx(entry->secid,
+		    security_secid_to_secctx(entry->secid.common,
 					     &secctx, &secctx_len) == 0) {
 			audit_log_format(audit_buf, " sec_obj=%s", secctx);
 			security_release_secctx(secctx, secctx_len);
@@ -569,7 +572,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
 		if (dev != NULL)
 			dev_put(dev);
 		if (entry != NULL &&
-		    security_secid_to_secctx(entry->secid,
+		    security_secid_to_secctx(entry->secid.common,
 					     &secctx, &secctx_len) == 0) {
 			audit_log_format(audit_buf, " sec_obj=%s", secctx);
 			security_release_secctx(secctx, secctx_len);
@@ -1124,7 +1127,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
 		if (ret_val != 0)
 			goto list_cb_failure;
 
-		secid = addr4->secid;
+		secid = addr4->secid.common;
 	} else {
 		ret_val = nla_put_in6_addr(cb_arg->skb,
 					   NLBL_UNLABEL_A_IPV6ADDR,
@@ -1138,7 +1141,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
 		if (ret_val != 0)
 			goto list_cb_failure;
 
-		secid = addr6->secid;
+		secid = addr6->secid.common;
 	}
 
 	ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len);
@@ -1543,7 +1546,7 @@ int __init netlbl_unlabel_defconf(void)
 	/* Only the kernel is allowed to call this function and the only time
 	 * it is called is at bootup before the audit subsystem is reporting
 	 * messages so don't worry to much about these values. */
-	security_task_getsecid(current, &audit_info.secid);
+	security_task_getsecid(current, &audit_info.secid.common);
 	audit_info.loginuid = GLOBAL_ROOT_UID;
 	audit_info.sessionid = 0;
 
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 2f328af91a52..415643011499 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -112,8 +112,8 @@ struct audit_buffer *netlbl_audit_start_common(int type,
 			 from_kuid(&init_user_ns, audit_info->loginuid),
 			 audit_info->sessionid);
 
-	if (audit_info->secid != 0 &&
-	    security_secid_to_secctx(audit_info->secid,
+	if (audit_info->secid.common != 0 &&
+	    security_secid_to_secctx(audit_info->secid.common,
 				     &secctx,
 				     &secctx_len) == 0) {
 		audit_log_format(audit_buf, " subj=%s", secctx);
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 4a397cde1a48..782ee194fdbd 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -48,7 +48,7 @@
 static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
 					    struct netlbl_audit *audit_info)
 {
-	security_task_getsecid(current, &audit_info->secid);
+	security_task_getsecid(current, &audit_info->secid.common);
 	audit_info->loginuid = audit_get_loginuid(current);
 	audit_info->sessionid = audit_get_sessionid(current);
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 5f48251c1319..63fa1ff1a71d 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1069,7 +1069,8 @@ static int xfrm_policy_match(const struct xfrm_policy *pol,
 
 	match = xfrm_selector_match(sel, fl, family);
 	if (match)
-		ret = security_xfrm_policy_lookup(pol->security, fl->flowi_secid,
+		ret = security_xfrm_policy_lookup(pol->security,
+						  fl->flowi_secid.common,
 						  dir);
 
 	return ret;
@@ -1182,7 +1183,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir,
 				goto out;
 			}
 			err = security_xfrm_policy_lookup(pol->security,
-						      fl->flowi_secid,
+						      fl->flowi_secid.common,
 						      dir);
 			if (!err) {
 				if (!xfrm_pol_hold_rcu(pol))
@@ -2365,7 +2366,7 @@ int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
 		return -EAFNOSUPPORT;
 
 	afinfo->decode_session(skb, fl, reverse);
-	err = security_xfrm_decode_session(skb, &fl->flowi_secid);
+	err = security_xfrm_decode_session(skb, &fl->flowi_secid.common);
 	rcu_read_unlock();
 	return err;
 }
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 8308281f3253..30086d2eaf6f 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1011,7 +1011,8 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
 		xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family);
 		memcpy(&x->mark, &pol->mark, sizeof(x->mark));
 
-		error = security_xfrm_state_alloc_acquire(x, pol->security, fl->flowi_secid);
+		error = security_xfrm_state_alloc_acquire(x, pol->security,
+						fl->flowi_secid.common);
 		if (error) {
 			x->km.state = XFRM_STATE_DEAD;
 			to_put = x;
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index eeaddfe0c0fb..d67faf77d6c5 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -225,14 +225,14 @@ int aa_audit_rule_known(struct audit_krule *rule)
 	return 0;
 }
 
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
+int aa_audit_rule_match(struct secids *sid, u32 field, u32 op, void *vrule,
 			struct audit_context *actx)
 {
 	struct aa_audit_rule *rule = vrule;
 	struct aa_label *label;
 	int found = 0;
 
-	label = aa_secid_to_label(sid);
+	label = aa_secid_to_label(sid->apparmor);
 
 	if (!label)
 		return -ENOENT;
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index b8c8b1066b0a..8042046eef90 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -192,7 +192,7 @@ static inline int complain_error(int error)
 void aa_audit_rule_free(void *vrule);
 int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule);
 int aa_audit_rule_known(struct audit_krule *rule);
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
+int aa_audit_rule_match(struct secids *sid, u32 field, u32 op, void *vrule,
 			struct audit_context *actx);
 
 #endif /* __AA_AUDIT_H */
diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h
index dee6fa3b6081..81f29538e415 100644
--- a/security/apparmor/include/secid.h
+++ b/security/apparmor/include/secid.h
@@ -23,8 +23,9 @@ struct aa_label;
 #define AA_SECID_INVALID 0
 
 struct aa_label *aa_secid_to_label(u32 secid);
-int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
-int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
+int apparmor_secid_to_secctx(struct secids *secid, char **secdata, u32 *seclen);
+int apparmor_secctx_to_secid(const char *secdata, u32 seclen,
+			     struct secids *secid);
 void apparmor_release_secctx(char *secdata, u32 seclen);
 
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index b0bf6ffe6a97..b0200481c811 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -707,10 +707,10 @@ static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
 	return;
 }
 
-static void apparmor_task_getsecid(struct task_struct *p, u32 *secid)
+static void apparmor_task_getsecid(struct task_struct *p, struct secids *secid)
 {
 	struct aa_label *label = aa_get_task_label(p);
-	*secid = label->secid;
+	secid->apparmor = label->secid;
 	aa_put_label(label);
 }
 
@@ -1077,7 +1077,8 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock,
  * Sets the netlabel socket state on sk from parent
  */
 static int apparmor_socket_getpeersec_dgram(struct socket *sock,
-					    struct sk_buff *skb, u32 *secid)
+					    struct sk_buff *skb,
+					    struct secids *secid)
 
 {
 	/* TODO: requires secid support */
diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c
index f2f22d00db18..07a5024dd675 100644
--- a/security/apparmor/secid.c
+++ b/security/apparmor/secid.c
@@ -73,10 +73,10 @@ struct aa_label *aa_secid_to_label(u32 secid)
 	return label;
 }
 
-int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+int apparmor_secid_to_secctx(struct secids *secid, char **secdata, u32 *seclen)
 {
 	/* TODO: cache secctx and ref count so we don't have to recreate */
-	struct aa_label *label = aa_secid_to_label(secid);
+	struct aa_label *label = aa_secid_to_label(secid->apparmor);
 	int len;
 
 	AA_BUG(!secdata);
@@ -102,7 +102,8 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 	return 0;
 }
 
-int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
+int apparmor_secctx_to_secid(const char *secdata, u32 seclen,
+			     struct secids *secid)
 {
 	struct aa_label *label;
 
@@ -110,7 +111,7 @@ int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 				    seclen, GFP_KERNEL, false, false);
 	if (IS_ERR(label))
 		return PTR_ERR(label);
-	*secid = label->secid;
+	secid->apparmor = label->secid;
 
 	return 0;
 }
diff --git a/security/security.c b/security/security.c
index eea36930f6f3..785cd38b1245 100644
--- a/security/security.c
+++ b/security/security.c
@@ -129,6 +129,7 @@ int __init security_init(void)
 	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);
+	pr_info("LSM: secid size           = %zu\n", sizeof(struct secids));
 #endif /* CONFIG_SECURITY_LSM_DEBUG */
 
 	return 0;
@@ -1249,7 +1250,10 @@ EXPORT_SYMBOL(security_inode_listsecurity);
 
 void security_inode_getsecid(struct inode *inode, u32 *secid)
 {
-	call_void_hook(inode_getsecid, inode, secid);
+	struct secids ids;
+
+	call_void_hook(inode_getsecid, inode, &ids);
+	*secid = ids.common;
 }
 
 int security_inode_copy_up(struct dentry *src, struct cred **new)
@@ -1459,14 +1463,20 @@ void security_transfer_creds(struct cred *new, const struct cred *old)
 
 void security_cred_getsecid(const struct cred *c, u32 *secid)
 {
-	*secid = 0;
-	call_void_hook(cred_getsecid, c, secid);
+	struct secids ids;
+
+	ids.common = 0;
+	call_void_hook(cred_getsecid, c, &ids);
+	*secid = ids.common;
 }
 EXPORT_SYMBOL(security_cred_getsecid);
 
 int security_kernel_act_as(struct cred *new, u32 secid)
 {
-	return call_int_hook(kernel_act_as, 0, new, secid);
+	struct secids ids;
+
+	ids.common = secid;
+	return call_int_hook(kernel_act_as, 0, new, &ids);
 }
 
 int security_kernel_create_files_as(struct cred *new, struct inode *inode)
@@ -1525,8 +1535,11 @@ int security_task_getsid(struct task_struct *p)
 
 void security_task_getsecid(struct task_struct *p, u32 *secid)
 {
-	*secid = 0;
-	call_void_hook(task_getsecid, p, secid);
+	struct secids ids;
+
+	ids.common = 0;
+	call_void_hook(task_getsecid, p, &ids);
+	*secid = ids.common;
 }
 EXPORT_SYMBOL(security_task_getsecid);
 
@@ -1608,8 +1621,11 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 
 void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
 {
-	*secid = 0;
-	call_void_hook(ipc_getsecid, ipcp, secid);
+	struct secids ids;
+
+	ids.common = 0;
+	call_void_hook(ipc_getsecid, ipcp, &ids);
+	*secid = ids.common;
 }
 
 int security_msg_msg_alloc(struct msg_msg *msg)
@@ -1788,15 +1804,24 @@ EXPORT_SYMBOL(security_ismaclabel);
 
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
-	return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata,
+	struct secids ids;
+
+	ids.common = secid;
+	return call_int_hook(secid_to_secctx, -EOPNOTSUPP, &ids, secdata,
 				seclen);
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
 int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
 {
-	*secid = 0;
-	return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid);
+	struct secids ids;
+	int rc;
+
+	ids.common = 0;
+	rc = call_int_hook(secctx_to_secid, 0, secdata, seclen, &ids);
+	*secid = ids.common;
+
+	return rc;
 }
 EXPORT_SYMBOL(security_secctx_to_secid);
 
@@ -1933,8 +1958,14 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
 
 int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
 {
-	return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock,
-			     skb, secid);
+	struct secids ids;
+	int rc;
+
+	rc = call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock,
+			     skb, &ids);
+	*secid = ids.common;
+
+	return rc;
 }
 EXPORT_SYMBOL(security_socket_getpeersec_dgram);
 
@@ -2003,7 +2034,10 @@ EXPORT_SYMBOL(security_inet_conn_established);
 
 int security_secmark_relabel_packet(u32 secid)
 {
-	return call_int_hook(secmark_relabel_packet, 0, secid);
+	struct secids ids;
+
+	ids.common = secid;
+	return call_int_hook(secmark_relabel_packet, 0, &ids);
 }
 EXPORT_SYMBOL(security_secmark_relabel_packet);
 
@@ -2142,7 +2176,10 @@ EXPORT_SYMBOL(security_xfrm_state_alloc);
 int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
 				      struct xfrm_sec_ctx *polsec, u32 secid)
 {
-	return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, secid);
+	struct secids ids;
+
+	ids.common = secid;
+	return call_int_hook(xfrm_state_alloc_acquire, 0, x, polsec, &ids);
 }
 
 int security_xfrm_state_delete(struct xfrm_state *x)
@@ -2158,7 +2195,10 @@ void security_xfrm_state_free(struct xfrm_state *x)
 
 int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
 {
-	return call_int_hook(xfrm_policy_lookup, 0, ctx, fl_secid, dir);
+	struct secids ids;
+
+	ids.common = fl_secid;
+	return call_int_hook(xfrm_policy_lookup, 0, ctx, &ids, dir);
 }
 
 int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
@@ -2187,7 +2227,13 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
 
 int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
 {
-	return call_int_hook(xfrm_decode_session, 0, skb, secid, 1);
+	struct secids ids;
+	int rc;
+
+	rc = call_int_hook(xfrm_decode_session, 0, skb, &ids, 1);
+	*secid = ids.common;
+
+	return rc;
 }
 
 void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
@@ -2257,7 +2303,10 @@ void security_audit_rule_free(void *lsmrule)
 int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
 			      struct audit_context *actx)
 {
-	return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule,
+	struct secids ids;
+
+	ids.common = secid;
+	return call_int_hook(audit_rule_match, 0, &ids, field, op, lsmrule,
 				actx);
 }
 #endif /* CONFIG_AUDIT */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fcdf1ea3c438..c12c36f72258 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3426,15 +3426,15 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
 	return len;
 }
 
-static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
+static void selinux_inode_getsecid(struct inode *inode, struct secids *secid)
 {
 	struct inode_security_struct *isec = inode_security_novalidate(inode);
-	*secid = isec->sid;
+	secid->selinux = isec->sid;
 }
 
 static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
 {
-	u32 sid;
+	struct secids sids;
 	struct task_security_struct *tsec;
 	struct cred *new_creds = *new;
 
@@ -3446,8 +3446,8 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
 
 	tsec = selinux_cred(new_creds);
 	/* Get label from overlay inode and set it in create_sid */
-	selinux_inode_getsecid(d_inode(src), &sid);
-	tsec->create_sid = sid;
+	selinux_inode_getsecid(d_inode(src), &sids);
+	tsec->create_sid = sids.selinux;
 	*new = new_creds;
 	return 0;
 }
@@ -3864,28 +3864,28 @@ static void selinux_cred_transfer(struct cred *new, const struct cred *old)
 	*tsec = *old_tsec;
 }
 
-static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
+static void selinux_cred_getsecid(const struct cred *c, struct secids *secid)
 {
-	*secid = cred_sid(c);
+	secid->selinux = cred_sid(c);
 }
 
 /*
  * set the security data for a kernel service
  * - all the creation contexts are set to unlabelled
  */
-static int selinux_kernel_act_as(struct cred *new, u32 secid)
+static int selinux_kernel_act_as(struct cred *new, struct secids *secid)
 {
 	struct task_security_struct *tsec = selinux_cred(new);
 	u32 sid = current_sid();
 	int ret;
 
 	ret = avc_has_perm(&selinux_state,
-			   sid, secid,
+			   sid, secid->selinux,
 			   SECCLASS_KERNEL_SERVICE,
 			   KERNEL_SERVICE__USE_AS_OVERRIDE,
 			   NULL);
 	if (ret == 0) {
-		tsec->sid = secid;
+		tsec->sid = secid->selinux;
 		tsec->create_sid = 0;
 		tsec->keycreate_sid = 0;
 		tsec->sockcreate_sid = 0;
@@ -3997,9 +3997,9 @@ static int selinux_task_getsid(struct task_struct *p)
 			    PROCESS__GETSESSION, NULL);
 }
 
-static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
+static void selinux_task_getsecid(struct task_struct *p, struct secids *secid)
 {
-	*secid = task_sid(p);
+	secid->selinux = task_sid(p);
 }
 
 static int selinux_task_setnice(struct task_struct *p, int nice)
@@ -5024,7 +5024,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock,
 	return err;
 }
 
-static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
+static int selinux_socket_getpeersec_dgram(struct socket *sock,
+					   struct sk_buff *skb,
+					   struct secids *secid)
 {
 	u32 peer_secid = SECSID_NULL;
 	u16 family;
@@ -5046,7 +5048,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
 		selinux_skb_peerlbl_sid(skb, family, &peer_secid);
 
 out:
-	*secid = peer_secid;
+	secid->selinux = peer_secid;
 	if (peer_secid == SECSID_NULL)
 		return -EINVAL;
 	return 0;
@@ -5083,14 +5085,14 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
 	selinux_netlbl_sk_security_reset(newsksec);
 }
 
-static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
+static void selinux_sk_getsecid(struct sock *sk, struct secids *secid)
 {
 	if (!sk)
-		*secid = SECINITSID_ANY_SOCKET;
+		secid->selinux = SECINITSID_ANY_SOCKET;
 	else {
 		struct sk_security_struct *sksec = selinux_sock(sk);
 
-		*secid = sksec->sid;
+		secid->selinux = sksec->sid;
 	}
 }
 
@@ -5323,7 +5325,7 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
 	selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
 }
 
-static int selinux_secmark_relabel_packet(u32 sid)
+static int selinux_secmark_relabel_packet(struct secids *secid)
 {
 	const struct task_security_struct *__tsec;
 	u32 tsid;
@@ -5332,8 +5334,8 @@ static int selinux_secmark_relabel_packet(u32 sid)
 	tsid = __tsec->sid;
 
 	return avc_has_perm(&selinux_state,
-			    tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
-			    NULL);
+			    tsid, secid->selinux, SECCLASS_PACKET,
+			    PACKET__RELABELTO, NULL);
 }
 
 static void selinux_secmark_refcount_inc(void)
@@ -5349,7 +5351,7 @@ static void selinux_secmark_refcount_dec(void)
 static void selinux_req_classify_flow(const struct request_sock *req,
 				      struct flowi *fl)
 {
-	fl->flowi_secid = req->secid;
+	fl->flowi_secid.selinux = req->secid;
 }
 
 static int selinux_tun_dev_alloc_security(void **security)
@@ -6174,10 +6176,11 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 	return ipc_has_perm(ipcp, av);
 }
 
-static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
+static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp,
+				 struct secids *secid)
 {
 	struct ipc_security_struct *isec = selinux_ipc(ipcp);
-	*secid = isec->sid;
+	secid->selinux = isec->sid;
 }
 
 static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
@@ -6383,16 +6386,18 @@ static int selinux_ismaclabel(const char *name)
 	return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
 }
 
-static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static int selinux_secid_to_secctx(struct secids *secid, char **secdata,
+				   u32 *seclen)
 {
-	return security_sid_to_context(&selinux_state, secid,
+	return security_sid_to_context(&selinux_state, secid->selinux,
 				       secdata, seclen);
 }
 
-static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
+static int selinux_secctx_to_secid(const char *secdata, u32 seclen,
+				   struct secids *secid)
 {
 	return security_context_to_sid(&selinux_state, secdata, seclen,
-				       secid, GFP_KERNEL);
+				       &secid->selinux, GFP_KERNEL);
 }
 
 static void selinux_release_secctx(char *secdata, u32 seclen)
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
index 1bdf973433cc..c9cadad5660e 100644
--- a/security/selinux/include/audit.h
+++ b/security/selinux/include/audit.h
@@ -51,7 +51,7 @@ void selinux_audit_rule_free(void *rule);
  *	Returns 1 if the context id matches the rule, 0 if it does not, and
  *	-errno on failure.
  */
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule,
+int selinux_audit_rule_match(struct secids *sid, u32 field, u32 op, void *rule,
 			     struct audit_context *actx);
 
 /**
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index a0b465316292..99bac3ccfebd 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -20,10 +20,12 @@ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
 int selinux_xfrm_state_alloc(struct xfrm_state *x,
 			     struct xfrm_user_sec_ctx *uctx);
 int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
-				     struct xfrm_sec_ctx *polsec, u32 secid);
+				     struct xfrm_sec_ctx *polsec,
+				     const struct secids *secid);
 void selinux_xfrm_state_free(struct xfrm_state *x);
 int selinux_xfrm_state_delete(struct xfrm_state *x);
-int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
+int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx,
+			       struct secids *fl_secid, u8 dir);
 int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
 				      struct xfrm_policy *xp,
 				      const struct flowi *fl);
@@ -40,7 +42,8 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
 			      struct common_audit_data *ad);
 int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
 				struct common_audit_data *ad, u8 proto);
-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
+int selinux_xfrm_decode_session(struct sk_buff *skb, struct secids *sid,
+				int ckall);
 int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
 
 static inline void selinux_xfrm_notify_policyload(void)
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index c40914a157b7..efc87a76af72 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -122,7 +122,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
 		return NULL;
 
 	if ((secattr->flags & NETLBL_SECATTR_SECID) &&
-	    (secattr->attr.secid == sid))
+	    (secattr->attr.secid.selinux == sid))
 		return secattr;
 
 	return NULL;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 7f9c87b077f3..b79b5b2ddf59 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3410,7 +3410,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
 	return 0;
 }
 
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
+int selinux_audit_rule_match(struct secids *sid, u32 field, u32 op, void *vrule,
 			     struct audit_context *actx)
 {
 	struct selinux_state *state = &selinux_state;
@@ -3431,10 +3431,10 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
 		goto out;
 	}
 
-	ctxt = sidtab_search(&state->ss->sidtab, sid);
+	ctxt = sidtab_search(&state->ss->sidtab, sid->selinux);
 	if (unlikely(!ctxt)) {
 		WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
-			  sid);
+			  sid->selinux);
 		match = -ENOENT;
 		goto out;
 	}
@@ -3609,7 +3609,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state,
 	if (secattr->flags & NETLBL_SECATTR_CACHE)
 		*sid = *(u32 *)secattr->cache->data;
 	else if (secattr->flags & NETLBL_SECATTR_SECID)
-		*sid = secattr->attr.secid;
+		*sid = secattr->attr.secid.selinux;
 	else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
 		rc = -EIDRM;
 		ctx = sidtab_search(sidtab, SECINITSID_NETMSG);
@@ -3682,7 +3682,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state,
 	if (secattr->domain == NULL)
 		goto out;
 
-	secattr->attr.secid = sid;
+	secattr->attr.secid.selinux = sid;
 	secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
 	mls_export_netlbl_lvl(policydb, ctx, secattr);
 	rc = mls_export_netlbl_cat(policydb, ctx, secattr);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 8ffe7e1053c4..067dd8307a9b 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -153,7 +153,8 @@ static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
  * LSM hook implementation that authorizes that a flow can use a xfrm policy
  * rule.
  */
-int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
+int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx,
+				struct secids *fl_secid, u8 dir)
 {
 	int rc;
 
@@ -167,7 +168,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
 		return -EINVAL;
 
 	rc = avc_has_perm(&selinux_state,
-			  fl_secid, ctx->ctx_sid,
+			  fl_secid->selinux, ctx->ctx_sid,
 			  SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
 	return (rc == -EACCES ? -ESRCH : rc);
 }
@@ -200,14 +201,14 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
 
 	state_sid = x->security->ctx_sid;
 
-	if (fl->flowi_secid != state_sid)
+	if (fl->flowi_secid.selinux != state_sid)
 		return 0;
 
 	/* We don't need a separate SA Vs. policy polmatch check since the SA
 	 * is now of the same label as the flow and a flow Vs. policy polmatch
 	 * check had already happened in selinux_xfrm_policy_lookup() above. */
 	return (avc_has_perm(&selinux_state,
-			     fl->flowi_secid, state_sid,
+			     fl->flowi_secid.selinux, state_sid,
 			    SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
 			    NULL) ? 0 : 1);
 }
@@ -261,13 +262,14 @@ static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
  * LSM hook implementation that checks and/or returns the xfrm sid for the
  * incoming packet.
  */
-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
+int selinux_xfrm_decode_session(struct sk_buff *skb, struct secids *sid,
+				int ckall)
 {
 	if (skb == NULL) {
-		*sid = SECSID_NULL;
+		sid->selinux = SECSID_NULL;
 		return 0;
 	}
-	return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
+	return selinux_xfrm_skb_sid_ingress(skb, &sid->selinux, ckall);
 }
 
 int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
@@ -344,7 +346,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x,
  * on a secid.
  */
 int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
-				     struct xfrm_sec_ctx *polsec, u32 secid)
+				     struct xfrm_sec_ctx *polsec,
+				     const struct secids *secid)
 {
 	int rc;
 	struct xfrm_sec_ctx *ctx;
@@ -354,10 +357,10 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
 	if (!polsec)
 		return 0;
 
-	if (secid == 0)
+	if (!secid_valid(secid))
 		return -EINVAL;
 
-	rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
+	rc = security_sid_to_context(&selinux_state, secid->selinux, &ctx_str,
 				     &str_len);
 	if (rc)
 		return rc;
@@ -370,7 +373,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
 
 	ctx->ctx_doi = XFRM_SC_DOI_LSM;
 	ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
-	ctx->ctx_sid = secid;
+	ctx->ctx_sid = secid->selinux;
 	ctx->ctx_len = str_len;
 	memcpy(ctx->ctx_str, ctx_str, str_len);
 
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 489d49a20b47..1bbbd53de78b 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -550,7 +550,9 @@ struct smack_known *smk_import_entry(const char *string, int len)
 	skp->smk_secid = smack_next_secid++;
 	skp->smk_netlabel.domain = skp->smk_known;
 	skp->smk_netlabel.flags =
-		NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
+		NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL |
+		NETLBL_SECATTR_SECID;
+	skp->smk_netlabel.attr.secid.smack = skp->smk_secid;
 	/*
 	 * If direct labeling works use it.
 	 * Otherwise use mapped labeling.
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 2d1a3fba40eb..157c6a731305 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1471,11 +1471,11 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  * @inode: inode to extract the info from
  * @secid: where result will be saved
  */
-static void smack_inode_getsecid(struct inode *inode, u32 *secid)
+static void smack_inode_getsecid(struct inode *inode, struct secids *secid)
 {
 	struct smack_known *skp = smk_of_inode(inode);
 
-	*secid = skp->smk_secid;
+	secid->smack = skp->smk_secid;
 }
 
 /*
@@ -1941,12 +1941,15 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
 	struct task_smack *old_tsp = smack_cred(old);
 	struct task_smack *new_tsp = smack_cred(new);
 
-	new_tsp->smk_task = old_tsp->smk_task;
-	new_tsp->smk_forked = old_tsp->smk_task;
-	mutex_init(&new_tsp->smk_rules_lock);
-	INIT_LIST_HEAD(&new_tsp->smk_rules);
+	int rc;
+
+	init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
 
-	/* cbs copy rule list */
+	rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules,
+		GFP_KERNEL);
+	if (rc == 0)
+		rc = smk_copy_relabel(&new_tsp->smk_relabel,
+					&old_tsp->smk_relabel, GFP_KERNEL);
 }
 
 /**
@@ -1956,13 +1959,13 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
  *
  * Sets the secid to contain a u32 version of the smack label.
  */
-static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
+static void smack_cred_getsecid(const struct cred *cred, struct secids *secid)
 {
 	struct smack_known *skp;
 
 	rcu_read_lock();
 	skp = smk_of_task(smack_cred(cred));
-	*secid = skp->smk_secid;
+	secid->smack = skp->smk_secid;
 	rcu_read_unlock();
 }
 
@@ -1973,11 +1976,11 @@ static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
  *
  * Set the security data for a kernel service.
  */
-static int smack_kernel_act_as(struct cred *new, u32 secid)
+static int smack_kernel_act_as(struct cred *new, struct secids *secid)
 {
 	struct task_smack *new_tsp = smack_cred(new);
 
-	new_tsp->smk_task = smack_from_secid(secid);
+	new_tsp->smk_task = smack_from_secid(secid->smack);
 	return 0;
 }
 
@@ -2063,11 +2066,11 @@ static int smack_task_getsid(struct task_struct *p)
  *
  * Sets the secid to contain a u32 version of the smack label.
  */
-static void smack_task_getsecid(struct task_struct *p, u32 *secid)
+static void smack_task_getsecid(struct task_struct *p, struct secids *secid)
 {
 	struct smack_known *skp = smk_of_task_struct(p);
 
-	*secid = skp->smk_secid;
+	secid->smack = skp->smk_secid;
 }
 
 /**
@@ -3206,12 +3209,12 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
  * @ipp: the object permissions
  * @secid: where result will be saved
  */
-static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
+static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, struct secids *secid)
 {
 	struct smack_known **blob = smack_ipc(ipp);
 	struct smack_known *iskp = *blob;
 
-	*secid = iskp->smk_secid;
+	secid->smack = iskp->smk_secid;
 }
 
 /**
@@ -3724,7 +3727,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
 		/*
 		 * Looks like a fallback, which gives us a secid.
 		 */
-		return smack_from_secid(sap->attr.secid);
+		return smack_from_secid(sap->attr.secid.smack);
 	/*
 	 * Without guidance regarding the smack value
 	 * for the packet fall back on the network
@@ -3857,7 +3860,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		if (proto != IPPROTO_UDP && proto != IPPROTO_TCP)
 			break;
 #ifdef SMACK_IPV6_SECMARK_LABELING
-		if (skb && skb->secmark != 0)
+		if (skb)
 			skp = smack_from_secid(skb->secmark);
 		else
 			skp = smack_ipv6host_label(&sadd);
@@ -3928,7 +3931,8 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
  * Sets the netlabel socket state on sk from parent
  */
 static int smack_socket_getpeersec_dgram(struct socket *sock,
-					 struct sk_buff *skb, u32 *secid)
+					 struct sk_buff *skb,
+					 struct secids *secid)
 
 {
 	struct netlbl_lsm_secattr secattr;
@@ -3956,9 +3960,11 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
 		break;
 	case PF_INET:
 #ifdef CONFIG_SECURITY_SMACK_NETFILTER
-		s = skb->secmark;
-		if (s != 0)
-			break;
+		if (skb->secmark) {
+			s = skb->secmark;
+			if (s != 0)
+				break;
+		}
 #endif
 		/*
 		 * Translate what netlabel gave us.
@@ -3979,7 +3985,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
 #endif
 		break;
 	}
-	*secid = s;
+	secid->smack = s;
 	if (s == 0)
 		return -EINVAL;
 	return 0;
@@ -4053,9 +4059,11 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 	 * If there is no secmark fall back to CIPSO.
 	 * The secmark is assumed to reflect policy better.
 	 */
-	if (skb && skb->secmark != 0) {
-		skp = smack_from_secid(skb->secmark);
-		goto access_check;
+	if (skb) {
+		if (skb->secmark != 0) {
+			skp = smack_from_secid(skb->secmark);
+			goto access_check;
+		}
 	}
 #endif /* CONFIG_SECURITY_SMACK_NETFILTER */
 
@@ -4326,8 +4334,8 @@ static int smack_audit_rule_known(struct audit_krule *krule)
  * The core Audit hook. It's used to take the decision of
  * whether to audit or not to audit a given object.
  */
-static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
-				  struct audit_context *actx)
+static int smack_audit_rule_match(struct secids *secid, u32 field, u32 op,
+				  void *vrule, struct audit_context *actx)
 {
 	struct smack_known *skp;
 	char *rule = vrule;
@@ -4340,7 +4348,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
 	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
 		return 0;
 
-	skp = smack_from_secid(secid);
+	skp = smack_from_secid(secid->smack);
 
 	/*
 	 * No need to do string comparisons. If a match occurs,
@@ -4380,9 +4388,10 @@ static int smack_ismaclabel(const char *name)
  *
  * Exists for networking code.
  */
-static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static int smack_secid_to_secctx(struct secids *secid, char **secdata,
+					u32 *seclen)
 {
-	struct smack_known *skp = smack_from_secid(secid);
+	struct smack_known *skp = smack_from_secid(secid->smack);
 
 	if (secdata)
 		*secdata = skp->smk_known;
@@ -4398,14 +4407,15 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
  *
  * Exists for audit and networking code.
  */
-static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
+static int smack_secctx_to_secid(const char *secdata, u32 seclen,
+					struct secids *secid)
 {
 	struct smack_known *skp = smk_find_entry(secdata);
 
 	if (skp)
-		*secid = skp->smk_secid;
+		secid->smack = skp->smk_secid;
 	else
-		*secid = 0;
+		secid->smack = 0;
 	return 0;
 }
 
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 9d2dde608298..0a075c80abb4 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -197,7 +197,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
 
 	nap->loginuid = audit_get_loginuid(current);
 	nap->sessionid = audit_get_sessionid(current);
-	nap->secid = skp->smk_secid;
+	nap->secid.smack = skp->smk_secid;
 }
 
 /*
@@ -1165,6 +1165,7 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
 	u32 mask_bits = (1<<31);
 	__be32 nsa;
 	u32 temp_mask;
+	struct secids secid;
 
 	/*
 	 * Must have privilege.
@@ -1281,10 +1282,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
 	 * this host so that incoming packets get labeled.
 	 * but only if we didn't get the special CIPSO option
 	 */
-	if (rc == 0 && skp != NULL)
+	if (rc == 0 && skp != NULL) {
+		secid_init(&secid);
+		secid.smack = snp->smk_label->smk_secid;
 		rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
 			&snp->smk_host, &snp->smk_mask, PF_INET,
-			snp->smk_label->smk_secid, &audit_info);
+			&secid, &audit_info);
+	}
 
 	if (rc == 0)
 		rc = count;
@@ -2951,7 +2955,9 @@ static int __init smk_preset_netlabel(struct smack_known *skp)
 {
 	skp->smk_netlabel.domain = skp->smk_known;
 	skp->smk_netlabel.flags =
-		NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL;
+		NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL |
+		NETLBL_SECATTR_SECID;
+	skp->smk_netlabel.attr.secid.smack = skp->smk_secid;
 	return smk_netlbl_mls(smack_cipso_direct, skp->smk_known,
 				&skp->smk_netlabel, strlen(skp->smk_known));
 }
-- 
2.17.1


--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help