lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri,  2 Aug 2013 15:14:34 +0800
From:	Cong Wang <amwang@...hat.com>
To:	netdev@...r.kernel.org
Cc:	"David S. Miller" <davem@...emloft.net>,
	James Morris <james.l.morris@...cle.com>,
	Stephen Smalley <sds@...ho.nsa.gov>,
	Eric Paris <eparis@...isplace.org>,
	Paul Moore <pmoore@...hat.com>, linux-kernel@...r.kernel.org,
	linux-security-module@...r.kernel.org,
	Cong Wang <amwang@...hat.com>
Subject: [Patch net-next v2 8/8] selinux: use generic union inet_addr

From: Cong Wang <amwang@...hat.com>

selinux has some similar definition like union inet_addr,
it can re-use the generic union inet_addr too.

Cc: James Morris <james.l.morris@...cle.com>
Cc: Stephen Smalley <sds@...ho.nsa.gov>
Cc: Eric Paris <eparis@...isplace.org>
Cc: Paul Moore <pmoore@...hat.com>
Cc: linux-kernel@...r.kernel.org
Cc: linux-security-module@...r.kernel.org
Signed-off-by: Cong Wang <amwang@...hat.com>
---
 include/linux/lsm_audit.h          |   19 +-----
 security/lsm_audit.c               |   58 ++++++++--------
 security/selinux/hooks.c           |  130 +++++++++++++++++-------------------
 security/selinux/include/netnode.h |    4 +-
 security/selinux/include/objsec.h  |    7 +--
 security/selinux/netnode.c         |  102 ++++++++--------------------
 security/smack/smack_lsm.c         |   19 +++---
 7 files changed, 138 insertions(+), 201 deletions(-)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 1cc89e9..48cab1e 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -21,23 +21,13 @@
 #include <linux/path.h>
 #include <linux/key.h>
 #include <linux/skbuff.h>
+#include <net/inet_addr.h>
 
 struct lsm_network_audit {
 	int netif;
 	struct sock *sk;
-	u16 family;
-	__be16 dport;
-	__be16 sport;
-	union {
-		struct {
-			__be32 daddr;
-			__be32 saddr;
-		} v4;
-		struct {
-			struct in6_addr daddr;
-			struct in6_addr saddr;
-		} v6;
-	} fam;
+	union inet_addr saddr;
+	union inet_addr daddr;
 };
 
 /* Auxiliary data to use in generating the audit record. */
@@ -83,9 +73,6 @@ struct common_audit_data {
 	}; /* per LSM data pointer union */
 };
 
-#define v4info fam.v4
-#define v6info fam.v6
-
 int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		struct common_audit_data *ad, u8 *proto);
 
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 8d8d97d..244c2a1 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 	if (ih == NULL)
 		return -EINVAL;
 
-	ad->u.net->v4info.saddr = ih->saddr;
-	ad->u.net->v4info.daddr = ih->daddr;
+	ad->u.net->saddr.sin.sin_addr.s_addr = ih->saddr;
+	ad->u.net->daddr.sin.sin_addr.s_addr = ih->daddr;
 
 	if (proto)
 		*proto = ih->protocol;
@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 	case IPPROTO_UDP: {
@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 	case IPPROTO_DCCP: {
@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 	case IPPROTO_SCTP: {
 		struct sctphdr *sh = sctp_hdr(skb);
 		if (sh == NULL)
 			break;
-		ad->u.net->sport = sh->source;
-		ad->u.net->dport = sh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(sh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(sh->dest));
 		break;
 	}
 	default:
@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 	ip6 = ipv6_hdr(skb);
 	if (ip6 == NULL)
 		return -EINVAL;
-	ad->u.net->v6info.saddr = ip6->saddr;
-	ad->u.net->v6info.daddr = ip6->daddr;
+	ad->u.net->saddr.sin6.sin6_addr = ip6->saddr;
+	ad->u.net->daddr.sin6.sin6_addr = ip6->daddr;
 	ret = 0;
 	/* IPv6 can have several extension header before the Transport header
 	 * skip them */
@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 	case IPPROTO_UDP: {
@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 	case IPPROTO_DCCP: {
@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 	case IPPROTO_SCTP: {
@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
 		if (sh == NULL)
 			break;
-		ad->u.net->sport = sh->source;
-		ad->u.net->dport = sh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(sh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(sh->dest));
 		break;
 	}
 	default:
@@ -333,21 +333,21 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 			}
 		}
 
-		switch (a->u.net->family) {
+		switch (a->u.net->saddr.sa.sa_family) {
 		case AF_INET:
-			print_ipv4_addr(ab, a->u.net->v4info.saddr,
-					a->u.net->sport,
+			print_ipv4_addr(ab, a->u.net->saddr.sin.sin_addr.s_addr,
+					a->u.net->saddr.sin.sin_port,
 					"saddr", "src");
-			print_ipv4_addr(ab, a->u.net->v4info.daddr,
-					a->u.net->dport,
+			print_ipv4_addr(ab, a->u.net->daddr.sin.sin_addr.s_addr,
+					a->u.net->daddr.sin.sin_port,
 					"daddr", "dest");
 			break;
 		case AF_INET6:
-			print_ipv6_addr(ab, &a->u.net->v6info.saddr,
-					a->u.net->sport,
+			print_ipv6_addr(ab, &a->u.net->saddr.sin6.sin6_addr,
+					a->u.net->saddr.sin.sin_port,
 					"saddr", "src");
-			print_ipv6_addr(ab, &a->u.net->v6info.daddr,
-					a->u.net->dport,
+			print_ipv6_addr(ab, &a->u.net->daddr.sin6.sin6_addr,
+					a->u.net->daddr.sin.sin_port,
 					"daddr", "dest");
 			break;
 		}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c956390..f9959c0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3595,8 +3595,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 	if (ihlen < sizeof(_iph))
 		goto out;
 
-	ad->u.net->v4info.saddr = ih->saddr;
-	ad->u.net->v4info.daddr = ih->daddr;
+	ad->u.net->saddr.sin.sin_addr.s_addr = ih->saddr;
+	ad->u.net->daddr.sin.sin_addr.s_addr = ih->daddr;
 	ret = 0;
 
 	if (proto)
@@ -3614,8 +3614,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 
@@ -3630,8 +3630,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 
@@ -3646,8 +3646,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 
@@ -3674,8 +3674,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 	if (ip6 == NULL)
 		goto out;
 
-	ad->u.net->v6info.saddr = ip6->saddr;
-	ad->u.net->v6info.daddr = ip6->daddr;
+	ad->u.net->saddr.sin6.sin6_addr = ip6->saddr;
+	ad->u.net->daddr.sin6.sin6_addr = ip6->daddr;
 	ret = 0;
 
 	nexthdr = ip6->nexthdr;
@@ -3695,8 +3695,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 
@@ -3707,8 +3707,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 
@@ -3719,8 +3719,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 
@@ -3735,18 +3735,17 @@ out:
 #endif /* IPV6 */
 
 static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
-			     char **_addrp, int src, u8 *proto)
+			     union inet_addr **_addrp, int src, u8 *proto)
 {
-	char *addrp;
+	union inet_addr *addrp;
 	int ret;
+	sa_family_t family = src ? ad->u.net->saddr.sa.sa_family : ad->u.net->daddr.sa.sa_family;
 
-	switch (ad->u.net->family) {
+	switch (family) {
 	case PF_INET:
 		ret = selinux_parse_skb_ipv4(skb, ad, proto);
 		if (ret)
 			goto parse_error;
-		addrp = (char *)(src ? &ad->u.net->v4info.saddr :
-				       &ad->u.net->v4info.daddr);
 		goto okay;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -3754,13 +3753,11 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
 		ret = selinux_parse_skb_ipv6(skb, ad, proto);
 		if (ret)
 			goto parse_error;
-		addrp = (char *)(src ? &ad->u.net->v6info.saddr :
-				       &ad->u.net->v6info.daddr);
 		goto okay;
 #endif	/* IPV6 */
 	default:
 		addrp = NULL;
-		goto okay;
+		goto save;
 	}
 
 parse_error:
@@ -3770,6 +3767,8 @@ parse_error:
 	return ret;
 
 okay:
+	addrp = src ? &ad->u.net->saddr : &ad->u.net->daddr;
+save:
 	if (_addrp)
 		*_addrp = addrp;
 	return 0;
@@ -3912,25 +3911,15 @@ 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;
+		union inet_addr *addrp = (union inet_addr *)address;
 		struct sk_security_struct *sksec = sk->sk_security;
 		struct common_audit_data ad;
 		struct lsm_network_audit net = {0,};
-		struct sockaddr_in *addr4 = NULL;
-		struct sockaddr_in6 *addr6 = NULL;
 		unsigned short snum;
 		u32 sid, node_perm;
 
-		if (family == PF_INET) {
-			addr4 = (struct sockaddr_in *)address;
-			snum = ntohs(addr4->sin_port);
-			addrp = (char *)&addr4->sin_addr.s_addr;
-		} else {
-			addr6 = (struct sockaddr_in6 *)address;
-			snum = ntohs(addr6->sin6_port);
-			addrp = (char *)&addr6->sin6_addr.s6_addr;
-		}
-
+		addrp->sa.sa_family = family;
+		snum = inet_addr_get_port(addrp);
 		if (snum) {
 			int low, high;
 
@@ -3943,8 +3932,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 					goto out;
 				ad.type = LSM_AUDIT_DATA_NET;
 				ad.u.net = &net;
-				ad.u.net->sport = htons(snum);
-				ad.u.net->family = family;
+				inet_addr_set_port(&ad.u.net->saddr, snum);
+				ad.u.net->saddr.sa.sa_family = family;
+				ad.u.net->daddr.sa.sa_family = family;
 				err = avc_has_perm(sksec->sid, sid,
 						   sksec->sclass,
 						   SOCKET__NAME_BIND, &ad);
@@ -3971,19 +3961,17 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 			break;
 		}
 
-		err = sel_netnode_sid(addrp, family, &sid);
+		err = sel_netnode_sid(addrp, &sid);
 		if (err)
 			goto out;
 
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.u.net = &net;
-		ad.u.net->sport = htons(snum);
-		ad.u.net->family = family;
+		inet_addr_set_port(&ad.u.net->saddr, snum);
+		ad.u.net->saddr.sa.sa_family = family;
+		ad.u.net->daddr.sa.sa_family = family;
 
-		if (family == PF_INET)
-			ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
-		else
-			ad.u.net->v6info.saddr = addr6->sin6_addr;
+		ad.u.net->saddr = *addrp;
 
 		err = avc_has_perm(sksec->sid, sid,
 				   sksec->sclass, node_perm, &ad);
@@ -4011,22 +3999,18 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 	    sksec->sclass == SECCLASS_DCCP_SOCKET) {
 		struct common_audit_data ad;
 		struct lsm_network_audit net = {0,};
-		struct sockaddr_in *addr4 = NULL;
-		struct sockaddr_in6 *addr6 = NULL;
+		union inet_addr *addrp = (union inet_addr *)address;
 		unsigned short snum;
 		u32 sid, perm;
 
 		if (sk->sk_family == PF_INET) {
-			addr4 = (struct sockaddr_in *)address;
 			if (addrlen < sizeof(struct sockaddr_in))
 				return -EINVAL;
-			snum = ntohs(addr4->sin_port);
 		} else {
-			addr6 = (struct sockaddr_in6 *)address;
 			if (addrlen < SIN6_LEN_RFC2133)
 				return -EINVAL;
-			snum = ntohs(addr6->sin6_port);
 		}
+		snum = inet_addr_get_port(addrp);
 
 		err = sel_netport_sid(sk->sk_protocol, snum, &sid);
 		if (err)
@@ -4037,8 +4021,9 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.u.net = &net;
-		ad.u.net->dport = htons(snum);
-		ad.u.net->family = sk->sk_family;
+		inet_addr_set_port(&ad.u.net->daddr, snum);
+		ad.u.net->saddr.sa.sa_family = sk->sk_family;
+		ad.u.net->daddr.sa.sa_family = sk->sk_family;
 		err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
 		if (err)
 			goto out;
@@ -4169,7 +4154,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,
 			    &ad);
 }
 
-static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
+static int selinux_inet_sys_rcv_skb(int ifindex, union inet_addr *addrp,
 				    u32 peer_sid,
 				    struct common_audit_data *ad)
 {
@@ -4185,7 +4170,7 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
 	if (err)
 		return err;
 
-	err = sel_netnode_sid(addrp, family, &node_sid);
+	err = sel_netnode_sid(addrp, &node_sid);
 	if (err)
 		return err;
 	return avc_has_perm(peer_sid, node_sid,
@@ -4200,12 +4185,13 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 	u32 sk_sid = sksec->sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = skb->skb_iif;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
 	if (err)
 		return err;
@@ -4233,7 +4219,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	u32 sk_sid = sksec->sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 secmark_active;
 	u8 peerlbl_active;
 
@@ -4259,7 +4245,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = skb->skb_iif;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
 	if (err)
 		return err;
@@ -4270,7 +4257,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
 		if (err)
 			return err;
-		err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp, family,
+		addrp->sa.sa_family = family;
+		err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp,
 					       peer_sid, &ad);
 		if (err) {
 			selinux_netlbl_err(skb, err, 0);
@@ -4621,7 +4609,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
 				       u16 family)
 {
 	int err;
-	char *addrp;
+	union inet_addr *addrp;
 	u32 peer_sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
@@ -4644,12 +4632,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
 		return NF_DROP;
 
 	if (peerlbl_active) {
-		err = selinux_inet_sys_rcv_skb(ifindex, addrp, family,
+		addrp->sa.sa_family = family;
+		err = selinux_inet_sys_rcv_skb(ifindex, addrp,
 					       peer_sid, &ad);
 		if (err) {
 			selinux_netlbl_err(skb, err, 1);
@@ -4732,7 +4722,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 	struct sk_security_struct *sksec;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 proto;
 
 	if (sk == NULL)
@@ -4742,7 +4732,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
 		return NF_DROP;
 
@@ -4765,7 +4756,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 	struct sock *sk;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 secmark_active;
 	u8 peerlbl_active;
 
@@ -4813,7 +4804,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
 		return NF_DROP;
 
@@ -4832,7 +4824,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 				 SECCLASS_NETIF, NETIF__EGRESS, &ad))
 			return NF_DROP_ERR(-ECONNREFUSED);
 
-		if (sel_netnode_sid(addrp, family, &node_sid))
+		if (sel_netnode_sid(addrp, &node_sid))
 			return NF_DROP;
 		if (avc_has_perm(peer_sid, node_sid,
 				 SECCLASS_NODE, NODE__SENDTO, &ad))
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index df7a5ed..f32c909 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -27,6 +27,8 @@
 #ifndef _SELINUX_NETNODE_H
 #define _SELINUX_NETNODE_H
 
-int sel_netnode_sid(void *addr, u16 family, u32 *sid);
+#include <net/inet_addr.h>
+
+int sel_netnode_sid(union inet_addr *addr, u32 *sid);
 
 #endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index aa47bca..a46caaf 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -24,6 +24,7 @@
 #include <linux/binfmts.h>
 #include <linux/in.h>
 #include <linux/spinlock.h>
+#include <net/inet_addr.h>
 #include "flask.h"
 #include "avc.h"
 
@@ -80,12 +81,8 @@ struct netif_security_struct {
 };
 
 struct netnode_security_struct {
-	union {
-		__be32 ipv4;		/* IPv4 node address */
-		struct in6_addr ipv6;	/* IPv6 node address */
-	} addr;
+	union inet_addr addr;
 	u32 sid;			/* SID for this node */
-	u16 family;			/* address family */
 };
 
 struct netport_security_struct {
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index c5454c0..713f14e 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -68,79 +68,49 @@ static LIST_HEAD(sel_netnode_list);
 static DEFINE_SPINLOCK(sel_netnode_lock);
 static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
 
-/**
- * sel_netnode_hashfn_ipv4 - IPv4 hashing function for the node table
- * @addr: IPv4 address
- *
- * Description:
- * This is the IPv4 hashing function for the node interface table, it returns
- * the bucket number for the given IP address.
- *
- */
-static unsigned int sel_netnode_hashfn_ipv4(__be32 addr)
-{
-	/* at some point we should determine if the mismatch in byte order
-	 * affects the hash function dramatically */
-	return (addr & (SEL_NETNODE_HASH_SIZE - 1));
-}
 
 /**
- * sel_netnode_hashfn_ipv6 - IPv6 hashing function for the node table
- * @addr: IPv6 address
+ * sel_netnode_hashfn - IPv4/IPv6 hashing function for the node table
+ * @addr: generic IP address
  *
  * Description:
- * This is the IPv6 hashing function for the node interface table, it returns
+ * This is the IP hashing function for the node interface table, it returns
  * the bucket number for the given IP address.
  *
  */
-static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
+static unsigned int sel_netnode_hashfn(const union inet_addr *addr)
 {
-	/* just hash the least significant 32 bits to keep things fast (they
-	 * are the most likely to be different anyway), we can revisit this
-	 * later if needed */
-	return (addr->s6_addr32[3] & (SEL_NETNODE_HASH_SIZE - 1));
+	if (addr->sa.sa_family == PF_INET)
+		/* at some point we should determine if the mismatch in byte order
+		 * affects the hash function dramatically */
+		return (addr->sin.sin_addr.s_addr & (SEL_NETNODE_HASH_SIZE - 1));
+	else if (addr->sa.sa_family == PF_INET6)
+		/* just hash the least significant 32 bits to keep things fast (they
+		 * are the most likely to be different anyway), we can revisit this
+		 * later if needed */
+		return (addr->sin6.sin6_addr.s6_addr32[3] & (SEL_NETNODE_HASH_SIZE - 1));
+	else
+		BUG();
 }
 
 /**
  * sel_netnode_find - Search for a node record
  * @addr: IP address
- * @family: address family
  *
  * Description:
  * Search the network node table and return the record matching @addr.  If an
  * entry can not be found in the table return NULL.
  *
  */
-static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
+static struct sel_netnode *sel_netnode_find(const union inet_addr *addr)
 {
 	unsigned int idx;
 	struct sel_netnode *node;
 
-	switch (family) {
-	case PF_INET:
-		idx = sel_netnode_hashfn_ipv4(*(__be32 *)addr);
-		break;
-	case PF_INET6:
-		idx = sel_netnode_hashfn_ipv6(addr);
-		break;
-	default:
-		BUG();
-		return NULL;
-	}
-
+	idx = sel_netnode_hashfn(addr);
 	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
-		if (node->nsec.family == family)
-			switch (family) {
-			case PF_INET:
-				if (node->nsec.addr.ipv4 == *(__be32 *)addr)
-					return node;
-				break;
-			case PF_INET6:
-				if (ipv6_addr_equal(&node->nsec.addr.ipv6,
-						    addr))
-					return node;
-				break;
-			}
+		if (inet_addr_equal(&node->nsec.addr, addr))
+			return node;
 
 	return NULL;
 }
@@ -156,18 +126,9 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
 static void sel_netnode_insert(struct sel_netnode *node)
 {
 	unsigned int idx;
+	union inet_addr *addr = &node->nsec.addr;
 
-	switch (node->nsec.family) {
-	case PF_INET:
-		idx = sel_netnode_hashfn_ipv4(node->nsec.addr.ipv4);
-		break;
-	case PF_INET6:
-		idx = sel_netnode_hashfn_ipv6(&node->nsec.addr.ipv6);
-		break;
-	default:
-		BUG();
-	}
-
+	idx = sel_netnode_hashfn(addr);
 	/* we need to impose a limit on the growth of the hash table so check
 	 * this bucket to make sure it is within the specified bounds */
 	list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
@@ -186,7 +147,6 @@ static void sel_netnode_insert(struct sel_netnode *node)
 /**
  * sel_netnode_sid_slow - Lookup the SID of a network address using the policy
  * @addr: the IP address
- * @family: the address family
  * @sid: node SID
  *
  * Description:
@@ -196,14 +156,14 @@ static void sel_netnode_insert(struct sel_netnode *node)
  * failure.
  *
  */
-static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
+static int sel_netnode_sid_slow(union inet_addr *addr, u32 *sid)
 {
 	int ret = -ENOMEM;
 	struct sel_netnode *node;
 	struct sel_netnode *new = NULL;
 
 	spin_lock_bh(&sel_netnode_lock);
-	node = sel_netnode_find(addr, family);
+	node = sel_netnode_find(addr);
 	if (node != NULL) {
 		*sid = node->nsec.sid;
 		spin_unlock_bh(&sel_netnode_lock);
@@ -212,16 +172,16 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
 	new = kzalloc(sizeof(*new), GFP_ATOMIC);
 	if (new == NULL)
 		goto out;
-	switch (family) {
+	switch (addr->sa.sa_family) {
 	case PF_INET:
 		ret = security_node_sid(PF_INET,
 					addr, sizeof(struct in_addr), sid);
-		new->nsec.addr.ipv4 = *(__be32 *)addr;
+		new->nsec.addr = *addr;
 		break;
 	case PF_INET6:
 		ret = security_node_sid(PF_INET6,
 					addr, sizeof(struct in6_addr), sid);
-		new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
+		new->nsec.addr = *addr;
 		break;
 	default:
 		BUG();
@@ -229,7 +189,6 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
 	if (ret != 0)
 		goto out;
 
-	new->nsec.family = family;
 	new->nsec.sid = *sid;
 	sel_netnode_insert(new);
 
@@ -246,8 +205,7 @@ out:
 
 /**
  * sel_netnode_sid - Lookup the SID of a network address
- * @addr: the IP address
- * @family: the address family
+ * @addr: the generic IP address
  * @sid: node SID
  *
  * Description:
@@ -258,12 +216,12 @@ out:
  * on failure.
  *
  */
-int sel_netnode_sid(void *addr, u16 family, u32 *sid)
+int sel_netnode_sid(union inet_addr *addr, u32 *sid)
 {
 	struct sel_netnode *node;
 
 	rcu_read_lock();
-	node = sel_netnode_find(addr, family);
+	node = sel_netnode_find(addr);
 	if (node != NULL) {
 		*sid = node->nsec.sid;
 		rcu_read_unlock();
@@ -271,7 +229,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
 	}
 	rcu_read_unlock();
 
-	return sel_netnode_sid_slow(addr, family, sid);
+	return sel_netnode_sid_slow(addr, sid);
 }
 
 /**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 3f7682a..07a7184 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1900,9 +1900,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
 		struct lsm_network_audit net;
 
 		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-		ad.a.u.net->family = sap->sin_family;
-		ad.a.u.net->dport = sap->sin_port;
-		ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
+		ad.a.u.net->daddr = (union inet_addr )*sap;
 #endif
 		sk_lbl = SMACK_UNLABELED_SOCKET;
 		skp = ssp->smk_out;
@@ -2057,12 +2055,13 @@ auditout:
 
 #ifdef CONFIG_AUDIT
 	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-	ad.a.u.net->family = sk->sk_family;
-	ad.a.u.net->dport = port;
+	inet_addr_set_port(&ad.a.u.net->daddr, port);
+	ad.a.u.net->saddr.sa.sa_family = sk->sk_family;
+	ad.a.u.net->daddr.sa.sa_family = sk->sk_family;
 	if (act == SMK_RECEIVING)
-		ad.a.u.net->v6info.saddr = addr6->sin6_addr;
+		ad.a.u.net->saddr.sin6.sin6_addr = addr6->sin6_addr;
 	else
-		ad.a.u.net->v6info.daddr = addr6->sin6_addr;
+		ad.a.u.net->daddr.sin6.sin6_addr = addr6->sin6_addr;
 #endif
 	return smk_access(skp, object, MAY_WRITE, &ad);
 }
@@ -3204,7 +3203,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 #ifdef CONFIG_AUDIT
 		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-		ad.a.u.net->family = sk->sk_family;
+		ad.a.u.net->saddr.sa.sa_family = sk->sk_family;
+		ad.a.u.net->daddr.sa.sa_family = sk->sk_family;
 		ad.a.u.net->netif = skb->skb_iif;
 		ipv4_skb_to_auditdata(skb, &ad.a, NULL);
 #endif
@@ -3386,7 +3386,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 
 #ifdef CONFIG_AUDIT
 	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-	ad.a.u.net->family = family;
+	ad.a.u.net->saddr.sa.sa_family = family;
+	ad.a.u.net->daddr.sa.sa_family = family;
 	ad.a.u.net->netif = skb->skb_iif;
 	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
 #endif
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ