On 8/19/2013 3:14 AM, Cong Wang wrote:
> From: Cong Wang <amw...@redhat.com>
>
> selinux has some similar definition like union inet_addr,
> it can re-use the generic union inet_addr too.

I'm trying to understand what value this change adds.
All it appears to do is swap one set of inconvenient
structure members for a different set of inconvenient
structure members. Does it improve performance?


>
> Cc: James Morris <james.l.mor...@oracle.com>
> Cc: Stephen Smalley <s...@tycho.nsa.gov>
> Cc: Eric Paris <epa...@parisplace.org>
> Cc: Paul Moore <pmo...@redhat.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-security-mod...@vger.kernel.org
> Signed-off-by: Cong Wang <amw...@redhat.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 eefbd10..9a80923 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;
> @@ -2055,12 +2053,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 = address->sin6_addr;
> +             ad.a.u.net->saddr.sin6.sin6_addr = address->sin6_addr;
>       else
> -             ad.a.u.net->v6info.daddr = address->sin6_addr;
> +             ad.a.u.net->daddr.sin6.sin6_addr = address->sin6_addr;
>  #endif
>       return smk_access(skp, object, MAY_WRITE, &ad);
>  }
> @@ -3202,7 +3201,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
> @@ -3384,7 +3384,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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to