Commit 48c62af6 authored by Eric Paris's avatar Eric Paris Committed by Linus Torvalds

LSM: shrink the common_audit_data data union

After shrinking the common_audit_data stack usage for private LSM data I'm
not going to shrink the data union.  To do this I'm going to move anything
larger than 2 void * ptrs to it's own structure and require it to be declared
separately on the calling stack.  Thus hot paths which don't need more than
a couple pointer don't have to declare space to hold large unneeded
structures.  I could get this down to one void * by dealing with the key
struct and the struct path.  We'll see if that is helpful after taking care of
networking.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3b3b0e4f
...@@ -22,6 +22,23 @@ ...@@ -22,6 +22,23 @@
#include <linux/key.h> #include <linux/key.h>
#include <linux/skbuff.h> #include <linux/skbuff.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;
};
/* Auxiliary data to use in generating the audit record. */ /* Auxiliary data to use in generating the audit record. */
struct common_audit_data { struct common_audit_data {
...@@ -41,23 +58,7 @@ struct common_audit_data { ...@@ -41,23 +58,7 @@ struct common_audit_data {
struct path path; struct path path;
struct dentry *dentry; struct dentry *dentry;
struct inode *inode; struct inode *inode;
struct { struct lsm_network_audit *net;
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;
} net;
int cap; int cap;
int ipc_id; int ipc_id;
struct task_struct *tsk; struct task_struct *tsk;
......
...@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (ih == NULL) if (ih == NULL)
return -EINVAL; return -EINVAL;
ad->u.net.v4info.saddr = ih->saddr; ad->u.net->v4info.saddr = ih->saddr;
ad->u.net.v4info.daddr = ih->daddr; ad->u.net->v4info.daddr = ih->daddr;
if (proto) if (proto)
*proto = ih->protocol; *proto = ih->protocol;
...@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
case IPPROTO_UDP: { case IPPROTO_UDP: {
...@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
case IPPROTO_DCCP: { case IPPROTO_DCCP: {
...@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, ...@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
case IPPROTO_SCTP: { case IPPROTO_SCTP: {
struct sctphdr *sh = sctp_hdr(skb); struct sctphdr *sh = sctp_hdr(skb);
if (sh == NULL) if (sh == NULL)
break; break;
ad->u.net.sport = sh->source; ad->u.net->sport = sh->source;
ad->u.net.dport = sh->dest; ad->u.net->dport = sh->dest;
break; break;
} }
default: default:
...@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
ip6 = ipv6_hdr(skb); ip6 = ipv6_hdr(skb);
if (ip6 == NULL) if (ip6 == NULL)
return -EINVAL; return -EINVAL;
ad->u.net.v6info.saddr = ip6->saddr; ad->u.net->v6info.saddr = ip6->saddr;
ad->u.net.v6info.daddr = ip6->daddr; ad->u.net->v6info.daddr = ip6->daddr;
ret = 0; ret = 0;
/* IPv6 can have several extension header before the Transport header /* IPv6 can have several extension header before the Transport header
* skip them */ * skip them */
...@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
case IPPROTO_UDP: { case IPPROTO_UDP: {
...@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
case IPPROTO_DCCP: { case IPPROTO_DCCP: {
...@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
case IPPROTO_SCTP: { case IPPROTO_SCTP: {
...@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ...@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
if (sh == NULL) if (sh == NULL)
break; break;
ad->u.net.sport = sh->source; ad->u.net->sport = sh->source;
ad->u.net.dport = sh->dest; ad->u.net->dport = sh->dest;
break; break;
} }
default: default:
...@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
} }
break; break;
case LSM_AUDIT_DATA_NET: case LSM_AUDIT_DATA_NET:
if (a->u.net.sk) { if (a->u.net->sk) {
struct sock *sk = a->u.net.sk; struct sock *sk = a->u.net->sk;
struct unix_sock *u; struct unix_sock *u;
int len = 0; int len = 0;
char *p = NULL; char *p = NULL;
...@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab,
} }
} }
switch (a->u.net.family) { switch (a->u.net->family) {
case AF_INET: case AF_INET:
print_ipv4_addr(ab, a->u.net.v4info.saddr, print_ipv4_addr(ab, a->u.net->v4info.saddr,
a->u.net.sport, a->u.net->sport,
"saddr", "src"); "saddr", "src");
print_ipv4_addr(ab, a->u.net.v4info.daddr, print_ipv4_addr(ab, a->u.net->v4info.daddr,
a->u.net.dport, a->u.net->dport,
"daddr", "dest"); "daddr", "dest");
break; break;
case AF_INET6: case AF_INET6:
print_ipv6_addr(ab, &a->u.net.v6info.saddr, print_ipv6_addr(ab, &a->u.net->v6info.saddr,
a->u.net.sport, a->u.net->sport,
"saddr", "src"); "saddr", "src");
print_ipv6_addr(ab, &a->u.net.v6info.daddr, print_ipv6_addr(ab, &a->u.net->v6info.daddr,
a->u.net.dport, a->u.net->dport,
"daddr", "dest"); "daddr", "dest");
break; break;
} }
if (a->u.net.netif > 0) { if (a->u.net->netif > 0) {
struct net_device *dev; struct net_device *dev;
/* NOTE: we always use init's namespace */ /* NOTE: we always use init's namespace */
dev = dev_get_by_index(&init_net, a->u.net.netif); dev = dev_get_by_index(&init_net, a->u.net->netif);
if (dev) { if (dev) {
audit_log_format(ab, " netif=%s", dev->name); audit_log_format(ab, " netif=%s", dev->name);
dev_put(dev); dev_put(dev);
......
...@@ -3517,8 +3517,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, ...@@ -3517,8 +3517,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
if (ihlen < sizeof(_iph)) if (ihlen < sizeof(_iph))
goto out; goto out;
ad->u.net.v4info.saddr = ih->saddr; ad->u.net->v4info.saddr = ih->saddr;
ad->u.net.v4info.daddr = ih->daddr; ad->u.net->v4info.daddr = ih->daddr;
ret = 0; ret = 0;
if (proto) if (proto)
...@@ -3536,8 +3536,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, ...@@ -3536,8 +3536,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
...@@ -3552,8 +3552,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, ...@@ -3552,8 +3552,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
...@@ -3568,8 +3568,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, ...@@ -3568,8 +3568,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
...@@ -3596,8 +3596,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, ...@@ -3596,8 +3596,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
if (ip6 == NULL) if (ip6 == NULL)
goto out; goto out;
ad->u.net.v6info.saddr = ip6->saddr; ad->u.net->v6info.saddr = ip6->saddr;
ad->u.net.v6info.daddr = ip6->daddr; ad->u.net->v6info.daddr = ip6->daddr;
ret = 0; ret = 0;
nexthdr = ip6->nexthdr; nexthdr = ip6->nexthdr;
...@@ -3617,8 +3617,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, ...@@ -3617,8 +3617,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
if (th == NULL) if (th == NULL)
break; break;
ad->u.net.sport = th->source; ad->u.net->sport = th->source;
ad->u.net.dport = th->dest; ad->u.net->dport = th->dest;
break; break;
} }
...@@ -3629,8 +3629,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, ...@@ -3629,8 +3629,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
if (uh == NULL) if (uh == NULL)
break; break;
ad->u.net.sport = uh->source; ad->u.net->sport = uh->source;
ad->u.net.dport = uh->dest; ad->u.net->dport = uh->dest;
break; break;
} }
...@@ -3641,8 +3641,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, ...@@ -3641,8 +3641,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
if (dh == NULL) if (dh == NULL)
break; break;
ad->u.net.sport = dh->dccph_sport; ad->u.net->sport = dh->dccph_sport;
ad->u.net.dport = dh->dccph_dport; ad->u.net->dport = dh->dccph_dport;
break; break;
} }
...@@ -3662,13 +3662,13 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, ...@@ -3662,13 +3662,13 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
char *addrp; char *addrp;
int ret; int ret;
switch (ad->u.net.family) { switch (ad->u.net->family) {
case PF_INET: case PF_INET:
ret = selinux_parse_skb_ipv4(skb, ad, proto); ret = selinux_parse_skb_ipv4(skb, ad, proto);
if (ret) if (ret)
goto parse_error; goto parse_error;
addrp = (char *)(src ? &ad->u.net.v4info.saddr : addrp = (char *)(src ? &ad->u.net->v4info.saddr :
&ad->u.net.v4info.daddr); &ad->u.net->v4info.daddr);
goto okay; goto okay;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
...@@ -3676,8 +3676,8 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, ...@@ -3676,8 +3676,8 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
ret = selinux_parse_skb_ipv6(skb, ad, proto); ret = selinux_parse_skb_ipv6(skb, ad, proto);
if (ret) if (ret)
goto parse_error; goto parse_error;
addrp = (char *)(src ? &ad->u.net.v6info.saddr : addrp = (char *)(src ? &ad->u.net->v6info.saddr :
&ad->u.net.v6info.daddr); &ad->u.net->v6info.daddr);
goto okay; goto okay;
#endif /* IPV6 */ #endif /* IPV6 */
default: default:
...@@ -3752,6 +3752,7 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) ...@@ -3752,6 +3752,7 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
u32 tsid = task_sid(task); u32 tsid = task_sid(task);
if (sksec->sid == SECINITSID_KERNEL) if (sksec->sid == SECINITSID_KERNEL)
...@@ -3759,7 +3760,8 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) ...@@ -3759,7 +3760,8 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.sk = sk; ad.u.net = &net;
ad.u.net->sk = sk;
return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
} }
...@@ -3838,6 +3840,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -3838,6 +3840,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
struct sockaddr_in *addr4 = NULL; struct sockaddr_in *addr4 = NULL;
struct sockaddr_in6 *addr6 = NULL; struct sockaddr_in6 *addr6 = NULL;
unsigned short snum; unsigned short snum;
...@@ -3865,8 +3868,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -3865,8 +3868,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
goto out; goto out;
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.sport = htons(snum); ad.u.net = &net;
ad.u.net.family = family; ad.u.net->sport = htons(snum);
ad.u.net->family = family;
err = avc_has_perm(sksec->sid, sid, err = avc_has_perm(sksec->sid, sid,
sksec->sclass, sksec->sclass,
SOCKET__NAME_BIND, &ad); SOCKET__NAME_BIND, &ad);
...@@ -3899,13 +3903,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -3899,13 +3903,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.sport = htons(snum); ad.u.net = &net;
ad.u.net.family = family; ad.u.net->sport = htons(snum);
ad.u.net->family = family;
if (family == PF_INET) if (family == PF_INET)
ad.u.net.v4info.saddr = addr4->sin_addr.s_addr; ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
else else
ad.u.net.v6info.saddr = addr6->sin6_addr; ad.u.net->v6info.saddr = addr6->sin6_addr;
err = avc_has_perm(sksec->sid, sid, err = avc_has_perm(sksec->sid, sid,
sksec->sclass, node_perm, &ad); sksec->sclass, node_perm, &ad);
...@@ -3933,6 +3938,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, ...@@ -3933,6 +3938,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
sksec->sclass == SECCLASS_DCCP_SOCKET) { sksec->sclass == SECCLASS_DCCP_SOCKET) {
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
struct sockaddr_in *addr4 = NULL; struct sockaddr_in *addr4 = NULL;
struct sockaddr_in6 *addr6 = NULL; struct sockaddr_in6 *addr6 = NULL;
unsigned short snum; unsigned short snum;
...@@ -3959,8 +3965,9 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, ...@@ -3959,8 +3965,9 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.dport = htons(snum); ad.u.net = &net;
ad.u.net.family = sk->sk_family; ad.u.net->dport = htons(snum);
ad.u.net->family = sk->sk_family;
err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
if (err) if (err)
goto out; goto out;
...@@ -4050,11 +4057,13 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, ...@@ -4050,11 +4057,13 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
struct sk_security_struct *sksec_new = newsk->sk_security; struct sk_security_struct *sksec_new = newsk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
int err; int err;
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.sk = other; ad.u.net = &net;
ad.u.net->sk = other;
err = avc_has_perm(sksec_sock->sid, sksec_other->sid, err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
sksec_other->sclass, sksec_other->sclass,
...@@ -4082,10 +4091,12 @@ static int selinux_socket_unix_may_send(struct socket *sock, ...@@ -4082,10 +4091,12 @@ static int selinux_socket_unix_may_send(struct socket *sock,
struct sk_security_struct *osec = other->sk->sk_security; struct sk_security_struct *osec = other->sk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.sk = other->sk; ad.u.net = &net;
ad.u.net->sk = other->sk;
return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
&ad); &ad);
...@@ -4122,12 +4133,14 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, ...@@ -4122,12 +4133,14 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
u32 sk_sid = sksec->sid; u32 sk_sid = sksec->sid;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
char *addrp; char *addrp;
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.netif = skb->skb_iif; ad.u.net = &net;
ad.u.net.family = family; ad.u.net->netif = skb->skb_iif;
ad.u.net->family = family;
err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
if (err) if (err)
return err; return err;
...@@ -4155,6 +4168,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -4155,6 +4168,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
u32 sk_sid = sksec->sid; u32 sk_sid = sksec->sid;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
char *addrp; char *addrp;
u8 secmark_active; u8 secmark_active;
u8 peerlbl_active; u8 peerlbl_active;
...@@ -4180,8 +4194,9 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -4180,8 +4194,9 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.netif = skb->skb_iif; ad.u.net = &net;
ad.u.net.family = family; ad.u.net->netif = skb->skb_iif;
ad.u.net->family = family;
err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
if (err) if (err)
return err; return err;
...@@ -4517,6 +4532,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, ...@@ -4517,6 +4532,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
u32 peer_sid; u32 peer_sid;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
u8 secmark_active; u8 secmark_active;
u8 netlbl_active; u8 netlbl_active;
u8 peerlbl_active; u8 peerlbl_active;
...@@ -4535,8 +4551,9 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, ...@@ -4535,8 +4551,9 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.netif = ifindex; ad.u.net = &net;
ad.u.net.family = family; ad.u.net->netif = ifindex;
ad.u.net->family = family;
if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
return NF_DROP; return NF_DROP;
...@@ -4624,6 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, ...@@ -4624,6 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
struct sk_security_struct *sksec; struct sk_security_struct *sksec;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
char *addrp; char *addrp;
u8 proto; u8 proto;
...@@ -4633,8 +4651,9 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, ...@@ -4633,8 +4651,9 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.netif = ifindex; ad.u.net = &net;
ad.u.net.family = family; ad.u.net->netif = ifindex;
ad.u.net->family = family;
if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
return NF_DROP; return NF_DROP;
...@@ -4657,6 +4676,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, ...@@ -4657,6 +4676,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
struct sock *sk; struct sock *sk;
struct common_audit_data ad; struct common_audit_data ad;
struct selinux_audit_data sad = {0,}; struct selinux_audit_data sad = {0,};
struct lsm_network_audit net = {0,};
char *addrp; char *addrp;
u8 secmark_active; u8 secmark_active;
u8 peerlbl_active; u8 peerlbl_active;
...@@ -4704,8 +4724,9 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, ...@@ -4704,8 +4724,9 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
COMMON_AUDIT_DATA_INIT(&ad, NET); COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.selinux_audit_data = &sad; ad.selinux_audit_data = &sad;
ad.u.net.netif = ifindex; ad.u.net = &net;
ad.u.net.family = family; ad.u.net->netif = ifindex;
ad.u.net->family = family;
if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
return NF_DROP; return NF_DROP;
......
...@@ -325,6 +325,14 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, ...@@ -325,6 +325,14 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
a->a.smack_audit_data->function = func; a->a.smack_audit_data->function = func;
} }
static inline void smk_ad_init_net(struct smk_audit_info *a, const char *func,
char type, struct lsm_network_audit *net)
{
smk_ad_init(a, func, type);
memset(net, 0, sizeof(*net));
a->a.u.net = net;
}
static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
struct task_struct *t) struct task_struct *t)
{ {
...@@ -348,7 +356,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, ...@@ -348,7 +356,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
struct sock *sk) struct sock *sk)
{ {
a->a.u.net.sk = sk; a->a.u.net->sk = sk;
} }
#else /* no AUDIT */ #else /* no AUDIT */
......
...@@ -1939,16 +1939,17 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) ...@@ -1939,16 +1939,17 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
char *hostsp; char *hostsp;
struct socket_smack *ssp = sk->sk_security; struct socket_smack *ssp = sk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
rcu_read_lock(); rcu_read_lock();
hostsp = smack_host_label(sap); hostsp = smack_host_label(sap);
if (hostsp != NULL) { if (hostsp != NULL) {
sk_lbl = SMACK_UNLABELED_SOCKET; sk_lbl = SMACK_UNLABELED_SOCKET;
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = sap->sin_family; ad.a.u.net->family = sap->sin_family;
ad.a.u.net.dport = sap->sin_port; ad.a.u.net->dport = sap->sin_port;
ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
#endif #endif
rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad);
} else { } else {
...@@ -2808,9 +2809,10 @@ static int smack_unix_stream_connect(struct sock *sock, ...@@ -2808,9 +2809,10 @@ static int smack_unix_stream_connect(struct sock *sock,
struct socket_smack *osp = other->sk_security; struct socket_smack *osp = other->sk_security;
struct socket_smack *nsp = newsk->sk_security; struct socket_smack *nsp = newsk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
int rc = 0; int rc = 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
smk_ad_setfield_u_net_sk(&ad, other); smk_ad_setfield_u_net_sk(&ad, other);
if (!capable(CAP_MAC_OVERRIDE)) if (!capable(CAP_MAC_OVERRIDE))
...@@ -2840,9 +2842,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) ...@@ -2840,9 +2842,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
struct socket_smack *ssp = sock->sk->sk_security; struct socket_smack *ssp = sock->sk->sk_security;
struct socket_smack *osp = other->sk->sk_security; struct socket_smack *osp = other->sk->sk_security;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
int rc = 0; int rc = 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
smk_ad_setfield_u_net_sk(&ad, other->sk); smk_ad_setfield_u_net_sk(&ad, other->sk);
if (!capable(CAP_MAC_OVERRIDE)) if (!capable(CAP_MAC_OVERRIDE))
...@@ -2990,6 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -2990,6 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
char *csp; char *csp;
int rc; int rc;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
return 0; return 0;
...@@ -3007,9 +3011,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) ...@@ -3007,9 +3011,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr);
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = sk->sk_family; ad.a.u.net->family = sk->sk_family;
ad.a.u.net.netif = skb->skb_iif; ad.a.u.net->netif = skb->skb_iif;
ipv4_skb_to_auditdata(skb, &ad.a, NULL); ipv4_skb_to_auditdata(skb, &ad.a, NULL);
#endif #endif
/* /*
...@@ -3152,6 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, ...@@ -3152,6 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
char *sp; char *sp;
int rc; int rc;
struct smk_audit_info ad; struct smk_audit_info ad;
struct lsm_network_audit net;
/* handle mapped IPv4 packets arriving via IPv6 sockets */ /* handle mapped IPv4 packets arriving via IPv6 sockets */
if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
...@@ -3166,9 +3171,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, ...@@ -3166,9 +3171,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr);
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ad.a.u.net.family = family; ad.a.u.net->family = family;
ad.a.u.net.netif = skb->skb_iif; ad.a.u.net->netif = skb->skb_iif;
ipv4_skb_to_auditdata(skb, &ad.a, NULL); ipv4_skb_to_auditdata(skb, &ad.a, NULL);
#endif #endif
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment