diff options
author | Eric Paris <eparis@redhat.com> | 2012-04-02 13:15:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-03 12:49:10 -0400 |
commit | 48c62af68a403ef1655546bd3e021070c8508573 (patch) | |
tree | ba938e4fb45d5bdaad2dad44071d0625f8e36945 | |
parent | 3b3b0e4fc15efa507b902d90cea39e496a523c3b (diff) |
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: Eric Paris <eparis@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/lsm_audit.h | 35 | ||||
-rw-r--r-- | security/lsm_audit.c | 66 | ||||
-rw-r--r-- | security/selinux/hooks.c | 105 | ||||
-rw-r--r-- | security/smack/smack.h | 10 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 29 |
5 files changed, 140 insertions, 105 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index 6f4fb37aac88..d1b073ffec24 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h | |||
@@ -22,6 +22,23 @@ | |||
22 | #include <linux/key.h> | 22 | #include <linux/key.h> |
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | 24 | ||
25 | struct lsm_network_audit { | ||
26 | int netif; | ||
27 | struct sock *sk; | ||
28 | u16 family; | ||
29 | __be16 dport; | ||
30 | __be16 sport; | ||
31 | union { | ||
32 | struct { | ||
33 | __be32 daddr; | ||
34 | __be32 saddr; | ||
35 | } v4; | ||
36 | struct { | ||
37 | struct in6_addr daddr; | ||
38 | struct in6_addr saddr; | ||
39 | } v6; | ||
40 | } fam; | ||
41 | }; | ||
25 | 42 | ||
26 | /* Auxiliary data to use in generating the audit record. */ | 43 | /* Auxiliary data to use in generating the audit record. */ |
27 | struct common_audit_data { | 44 | struct common_audit_data { |
@@ -41,23 +58,7 @@ struct common_audit_data { | |||
41 | struct path path; | 58 | struct path path; |
42 | struct dentry *dentry; | 59 | struct dentry *dentry; |
43 | struct inode *inode; | 60 | struct inode *inode; |
44 | struct { | 61 | struct lsm_network_audit *net; |
45 | int netif; | ||
46 | struct sock *sk; | ||
47 | u16 family; | ||
48 | __be16 dport; | ||
49 | __be16 sport; | ||
50 | union { | ||
51 | struct { | ||
52 | __be32 daddr; | ||
53 | __be32 saddr; | ||
54 | } v4; | ||
55 | struct { | ||
56 | struct in6_addr daddr; | ||
57 | struct in6_addr saddr; | ||
58 | } v6; | ||
59 | } fam; | ||
60 | } net; | ||
61 | int cap; | 62 | int cap; |
62 | int ipc_id; | 63 | int ipc_id; |
63 | struct task_struct *tsk; | 64 | struct task_struct *tsk; |
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 8b8f0902f6e5..e96c6aa17bb0 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, | |||
49 | if (ih == NULL) | 49 | if (ih == NULL) |
50 | return -EINVAL; | 50 | return -EINVAL; |
51 | 51 | ||
52 | ad->u.net.v4info.saddr = ih->saddr; | 52 | ad->u.net->v4info.saddr = ih->saddr; |
53 | ad->u.net.v4info.daddr = ih->daddr; | 53 | ad->u.net->v4info.daddr = ih->daddr; |
54 | 54 | ||
55 | if (proto) | 55 | if (proto) |
56 | *proto = ih->protocol; | 56 | *proto = ih->protocol; |
@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, | |||
64 | if (th == NULL) | 64 | if (th == NULL) |
65 | break; | 65 | break; |
66 | 66 | ||
67 | ad->u.net.sport = th->source; | 67 | ad->u.net->sport = th->source; |
68 | ad->u.net.dport = th->dest; | 68 | ad->u.net->dport = th->dest; |
69 | break; | 69 | break; |
70 | } | 70 | } |
71 | case IPPROTO_UDP: { | 71 | case IPPROTO_UDP: { |
@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, | |||
73 | if (uh == NULL) | 73 | if (uh == NULL) |
74 | break; | 74 | break; |
75 | 75 | ||
76 | ad->u.net.sport = uh->source; | 76 | ad->u.net->sport = uh->source; |
77 | ad->u.net.dport = uh->dest; | 77 | ad->u.net->dport = uh->dest; |
78 | break; | 78 | break; |
79 | } | 79 | } |
80 | case IPPROTO_DCCP: { | 80 | case IPPROTO_DCCP: { |
@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, | |||
82 | if (dh == NULL) | 82 | if (dh == NULL) |
83 | break; | 83 | break; |
84 | 84 | ||
85 | ad->u.net.sport = dh->dccph_sport; | 85 | ad->u.net->sport = dh->dccph_sport; |
86 | ad->u.net.dport = dh->dccph_dport; | 86 | ad->u.net->dport = dh->dccph_dport; |
87 | break; | 87 | break; |
88 | } | 88 | } |
89 | case IPPROTO_SCTP: { | 89 | case IPPROTO_SCTP: { |
90 | struct sctphdr *sh = sctp_hdr(skb); | 90 | struct sctphdr *sh = sctp_hdr(skb); |
91 | if (sh == NULL) | 91 | if (sh == NULL) |
92 | break; | 92 | break; |
93 | ad->u.net.sport = sh->source; | 93 | ad->u.net->sport = sh->source; |
94 | ad->u.net.dport = sh->dest; | 94 | ad->u.net->dport = sh->dest; |
95 | break; | 95 | break; |
96 | } | 96 | } |
97 | default: | 97 | default: |
@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
119 | ip6 = ipv6_hdr(skb); | 119 | ip6 = ipv6_hdr(skb); |
120 | if (ip6 == NULL) | 120 | if (ip6 == NULL) |
121 | return -EINVAL; | 121 | return -EINVAL; |
122 | ad->u.net.v6info.saddr = ip6->saddr; | 122 | ad->u.net->v6info.saddr = ip6->saddr; |
123 | ad->u.net.v6info.daddr = ip6->daddr; | 123 | ad->u.net->v6info.daddr = ip6->daddr; |
124 | ret = 0; | 124 | ret = 0; |
125 | /* IPv6 can have several extension header before the Transport header | 125 | /* IPv6 can have several extension header before the Transport header |
126 | * skip them */ | 126 | * skip them */ |
@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
140 | if (th == NULL) | 140 | if (th == NULL) |
141 | break; | 141 | break; |
142 | 142 | ||
143 | ad->u.net.sport = th->source; | 143 | ad->u.net->sport = th->source; |
144 | ad->u.net.dport = th->dest; | 144 | ad->u.net->dport = th->dest; |
145 | break; | 145 | break; |
146 | } | 146 | } |
147 | case IPPROTO_UDP: { | 147 | case IPPROTO_UDP: { |
@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
151 | if (uh == NULL) | 151 | if (uh == NULL) |
152 | break; | 152 | break; |
153 | 153 | ||
154 | ad->u.net.sport = uh->source; | 154 | ad->u.net->sport = uh->source; |
155 | ad->u.net.dport = uh->dest; | 155 | ad->u.net->dport = uh->dest; |
156 | break; | 156 | break; |
157 | } | 157 | } |
158 | case IPPROTO_DCCP: { | 158 | case IPPROTO_DCCP: { |
@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
162 | if (dh == NULL) | 162 | if (dh == NULL) |
163 | break; | 163 | break; |
164 | 164 | ||
165 | ad->u.net.sport = dh->dccph_sport; | 165 | ad->u.net->sport = dh->dccph_sport; |
166 | ad->u.net.dport = dh->dccph_dport; | 166 | ad->u.net->dport = dh->dccph_dport; |
167 | break; | 167 | break; |
168 | } | 168 | } |
169 | case IPPROTO_SCTP: { | 169 | case IPPROTO_SCTP: { |
@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
172 | sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); | 172 | sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); |
173 | if (sh == NULL) | 173 | if (sh == NULL) |
174 | break; | 174 | break; |
175 | ad->u.net.sport = sh->source; | 175 | ad->u.net->sport = sh->source; |
176 | ad->u.net.dport = sh->dest; | 176 | ad->u.net->dport = sh->dest; |
177 | break; | 177 | break; |
178 | } | 178 | } |
179 | default: | 179 | default: |
@@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
281 | } | 281 | } |
282 | break; | 282 | break; |
283 | case LSM_AUDIT_DATA_NET: | 283 | case LSM_AUDIT_DATA_NET: |
284 | if (a->u.net.sk) { | 284 | if (a->u.net->sk) { |
285 | struct sock *sk = a->u.net.sk; | 285 | struct sock *sk = a->u.net->sk; |
286 | struct unix_sock *u; | 286 | struct unix_sock *u; |
287 | int len = 0; | 287 | int len = 0; |
288 | char *p = NULL; | 288 | char *p = NULL; |
@@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
330 | } | 330 | } |
331 | } | 331 | } |
332 | 332 | ||
333 | switch (a->u.net.family) { | 333 | switch (a->u.net->family) { |
334 | case AF_INET: | 334 | case AF_INET: |
335 | print_ipv4_addr(ab, a->u.net.v4info.saddr, | 335 | print_ipv4_addr(ab, a->u.net->v4info.saddr, |
336 | a->u.net.sport, | 336 | a->u.net->sport, |
337 | "saddr", "src"); | 337 | "saddr", "src"); |
338 | print_ipv4_addr(ab, a->u.net.v4info.daddr, | 338 | print_ipv4_addr(ab, a->u.net->v4info.daddr, |
339 | a->u.net.dport, | 339 | a->u.net->dport, |
340 | "daddr", "dest"); | 340 | "daddr", "dest"); |
341 | break; | 341 | break; |
342 | case AF_INET6: | 342 | case AF_INET6: |
343 | print_ipv6_addr(ab, &a->u.net.v6info.saddr, | 343 | print_ipv6_addr(ab, &a->u.net->v6info.saddr, |
344 | a->u.net.sport, | 344 | a->u.net->sport, |
345 | "saddr", "src"); | 345 | "saddr", "src"); |
346 | print_ipv6_addr(ab, &a->u.net.v6info.daddr, | 346 | print_ipv6_addr(ab, &a->u.net->v6info.daddr, |
347 | a->u.net.dport, | 347 | a->u.net->dport, |
348 | "daddr", "dest"); | 348 | "daddr", "dest"); |
349 | break; | 349 | break; |
350 | } | 350 | } |
351 | if (a->u.net.netif > 0) { | 351 | if (a->u.net->netif > 0) { |
352 | struct net_device *dev; | 352 | struct net_device *dev; |
353 | 353 | ||
354 | /* NOTE: we always use init's namespace */ | 354 | /* NOTE: we always use init's namespace */ |
355 | dev = dev_get_by_index(&init_net, a->u.net.netif); | 355 | dev = dev_get_by_index(&init_net, a->u.net->netif); |
356 | if (dev) { | 356 | if (dev) { |
357 | audit_log_format(ab, " netif=%s", dev->name); | 357 | audit_log_format(ab, " netif=%s", dev->name); |
358 | dev_put(dev); | 358 | dev_put(dev); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3861ce4b1007..d85b793c9321 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3517,8 +3517,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
3517 | if (ihlen < sizeof(_iph)) | 3517 | if (ihlen < sizeof(_iph)) |
3518 | goto out; | 3518 | goto out; |
3519 | 3519 | ||
3520 | ad->u.net.v4info.saddr = ih->saddr; | 3520 | ad->u.net->v4info.saddr = ih->saddr; |
3521 | ad->u.net.v4info.daddr = ih->daddr; | 3521 | ad->u.net->v4info.daddr = ih->daddr; |
3522 | ret = 0; | 3522 | ret = 0; |
3523 | 3523 | ||
3524 | if (proto) | 3524 | if (proto) |
@@ -3536,8 +3536,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
3536 | if (th == NULL) | 3536 | if (th == NULL) |
3537 | break; | 3537 | break; |
3538 | 3538 | ||
3539 | ad->u.net.sport = th->source; | 3539 | ad->u.net->sport = th->source; |
3540 | ad->u.net.dport = th->dest; | 3540 | ad->u.net->dport = th->dest; |
3541 | break; | 3541 | break; |
3542 | } | 3542 | } |
3543 | 3543 | ||
@@ -3552,8 +3552,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
3552 | if (uh == NULL) | 3552 | if (uh == NULL) |
3553 | break; | 3553 | break; |
3554 | 3554 | ||
3555 | ad->u.net.sport = uh->source; | 3555 | ad->u.net->sport = uh->source; |
3556 | ad->u.net.dport = uh->dest; | 3556 | ad->u.net->dport = uh->dest; |
3557 | break; | 3557 | break; |
3558 | } | 3558 | } |
3559 | 3559 | ||
@@ -3568,8 +3568,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, | |||
3568 | if (dh == NULL) | 3568 | if (dh == NULL) |
3569 | break; | 3569 | break; |
3570 | 3570 | ||
3571 | ad->u.net.sport = dh->dccph_sport; | 3571 | ad->u.net->sport = dh->dccph_sport; |
3572 | ad->u.net.dport = dh->dccph_dport; | 3572 | ad->u.net->dport = dh->dccph_dport; |
3573 | break; | 3573 | break; |
3574 | } | 3574 | } |
3575 | 3575 | ||
@@ -3596,8 +3596,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
3596 | if (ip6 == NULL) | 3596 | if (ip6 == NULL) |
3597 | goto out; | 3597 | goto out; |
3598 | 3598 | ||
3599 | ad->u.net.v6info.saddr = ip6->saddr; | 3599 | ad->u.net->v6info.saddr = ip6->saddr; |
3600 | ad->u.net.v6info.daddr = ip6->daddr; | 3600 | ad->u.net->v6info.daddr = ip6->daddr; |
3601 | ret = 0; | 3601 | ret = 0; |
3602 | 3602 | ||
3603 | nexthdr = ip6->nexthdr; | 3603 | nexthdr = ip6->nexthdr; |
@@ -3617,8 +3617,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
3617 | if (th == NULL) | 3617 | if (th == NULL) |
3618 | break; | 3618 | break; |
3619 | 3619 | ||
3620 | ad->u.net.sport = th->source; | 3620 | ad->u.net->sport = th->source; |
3621 | ad->u.net.dport = th->dest; | 3621 | ad->u.net->dport = th->dest; |
3622 | break; | 3622 | break; |
3623 | } | 3623 | } |
3624 | 3624 | ||
@@ -3629,8 +3629,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
3629 | if (uh == NULL) | 3629 | if (uh == NULL) |
3630 | break; | 3630 | break; |
3631 | 3631 | ||
3632 | ad->u.net.sport = uh->source; | 3632 | ad->u.net->sport = uh->source; |
3633 | ad->u.net.dport = uh->dest; | 3633 | ad->u.net->dport = uh->dest; |
3634 | break; | 3634 | break; |
3635 | } | 3635 | } |
3636 | 3636 | ||
@@ -3641,8 +3641,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, | |||
3641 | if (dh == NULL) | 3641 | if (dh == NULL) |
3642 | break; | 3642 | break; |
3643 | 3643 | ||
3644 | ad->u.net.sport = dh->dccph_sport; | 3644 | ad->u.net->sport = dh->dccph_sport; |
3645 | ad->u.net.dport = dh->dccph_dport; | 3645 | ad->u.net->dport = dh->dccph_dport; |
3646 | break; | 3646 | break; |
3647 | } | 3647 | } |
3648 | 3648 | ||
@@ -3662,13 +3662,13 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, | |||
3662 | char *addrp; | 3662 | char *addrp; |
3663 | int ret; | 3663 | int ret; |
3664 | 3664 | ||
3665 | switch (ad->u.net.family) { | 3665 | switch (ad->u.net->family) { |
3666 | case PF_INET: | 3666 | case PF_INET: |
3667 | ret = selinux_parse_skb_ipv4(skb, ad, proto); | 3667 | ret = selinux_parse_skb_ipv4(skb, ad, proto); |
3668 | if (ret) | 3668 | if (ret) |
3669 | goto parse_error; | 3669 | goto parse_error; |
3670 | addrp = (char *)(src ? &ad->u.net.v4info.saddr : | 3670 | addrp = (char *)(src ? &ad->u.net->v4info.saddr : |
3671 | &ad->u.net.v4info.daddr); | 3671 | &ad->u.net->v4info.daddr); |
3672 | goto okay; | 3672 | goto okay; |
3673 | 3673 | ||
3674 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 3674 | #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 | ret = selinux_parse_skb_ipv6(skb, ad, proto); | 3676 | ret = selinux_parse_skb_ipv6(skb, ad, proto); |
3677 | if (ret) | 3677 | if (ret) |
3678 | goto parse_error; | 3678 | goto parse_error; |
3679 | addrp = (char *)(src ? &ad->u.net.v6info.saddr : | 3679 | addrp = (char *)(src ? &ad->u.net->v6info.saddr : |
3680 | &ad->u.net.v6info.daddr); | 3680 | &ad->u.net->v6info.daddr); |
3681 | goto okay; | 3681 | goto okay; |
3682 | #endif /* IPV6 */ | 3682 | #endif /* IPV6 */ |
3683 | default: | 3683 | default: |
@@ -3752,6 +3752,7 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | |||
3752 | struct sk_security_struct *sksec = sk->sk_security; | 3752 | struct sk_security_struct *sksec = sk->sk_security; |
3753 | struct common_audit_data ad; | 3753 | struct common_audit_data ad; |
3754 | struct selinux_audit_data sad = {0,}; | 3754 | struct selinux_audit_data sad = {0,}; |
3755 | struct lsm_network_audit net = {0,}; | ||
3755 | u32 tsid = task_sid(task); | 3756 | u32 tsid = task_sid(task); |
3756 | 3757 | ||
3757 | if (sksec->sid == SECINITSID_KERNEL) | 3758 | if (sksec->sid == SECINITSID_KERNEL) |
@@ -3759,7 +3760,8 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) | |||
3759 | 3760 | ||
3760 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3761 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3761 | ad.selinux_audit_data = &sad; | 3762 | ad.selinux_audit_data = &sad; |
3762 | ad.u.net.sk = sk; | 3763 | ad.u.net = &net; |
3764 | ad.u.net->sk = sk; | ||
3763 | 3765 | ||
3764 | return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); | 3766 | return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); |
3765 | } | 3767 | } |
@@ -3838,6 +3840,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3838 | struct sk_security_struct *sksec = sk->sk_security; | 3840 | struct sk_security_struct *sksec = sk->sk_security; |
3839 | struct common_audit_data ad; | 3841 | struct common_audit_data ad; |
3840 | struct selinux_audit_data sad = {0,}; | 3842 | struct selinux_audit_data sad = {0,}; |
3843 | struct lsm_network_audit net = {0,}; | ||
3841 | struct sockaddr_in *addr4 = NULL; | 3844 | struct sockaddr_in *addr4 = NULL; |
3842 | struct sockaddr_in6 *addr6 = NULL; | 3845 | struct sockaddr_in6 *addr6 = NULL; |
3843 | unsigned short snum; | 3846 | unsigned short snum; |
@@ -3865,8 +3868,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3865 | goto out; | 3868 | goto out; |
3866 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3869 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3867 | ad.selinux_audit_data = &sad; | 3870 | ad.selinux_audit_data = &sad; |
3868 | ad.u.net.sport = htons(snum); | 3871 | ad.u.net = &net; |
3869 | ad.u.net.family = family; | 3872 | ad.u.net->sport = htons(snum); |
3873 | ad.u.net->family = family; | ||
3870 | err = avc_has_perm(sksec->sid, sid, | 3874 | err = avc_has_perm(sksec->sid, sid, |
3871 | sksec->sclass, | 3875 | sksec->sclass, |
3872 | SOCKET__NAME_BIND, &ad); | 3876 | SOCKET__NAME_BIND, &ad); |
@@ -3899,13 +3903,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3899 | 3903 | ||
3900 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3904 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3901 | ad.selinux_audit_data = &sad; | 3905 | ad.selinux_audit_data = &sad; |
3902 | ad.u.net.sport = htons(snum); | 3906 | ad.u.net = &net; |
3903 | ad.u.net.family = family; | 3907 | ad.u.net->sport = htons(snum); |
3908 | ad.u.net->family = family; | ||
3904 | 3909 | ||
3905 | if (family == PF_INET) | 3910 | if (family == PF_INET) |
3906 | ad.u.net.v4info.saddr = addr4->sin_addr.s_addr; | 3911 | ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; |
3907 | else | 3912 | else |
3908 | ad.u.net.v6info.saddr = addr6->sin6_addr; | 3913 | ad.u.net->v6info.saddr = addr6->sin6_addr; |
3909 | 3914 | ||
3910 | err = avc_has_perm(sksec->sid, sid, | 3915 | err = avc_has_perm(sksec->sid, sid, |
3911 | sksec->sclass, node_perm, &ad); | 3916 | sksec->sclass, node_perm, &ad); |
@@ -3933,6 +3938,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3933 | sksec->sclass == SECCLASS_DCCP_SOCKET) { | 3938 | sksec->sclass == SECCLASS_DCCP_SOCKET) { |
3934 | struct common_audit_data ad; | 3939 | struct common_audit_data ad; |
3935 | struct selinux_audit_data sad = {0,}; | 3940 | struct selinux_audit_data sad = {0,}; |
3941 | struct lsm_network_audit net = {0,}; | ||
3936 | struct sockaddr_in *addr4 = NULL; | 3942 | struct sockaddr_in *addr4 = NULL; |
3937 | struct sockaddr_in6 *addr6 = NULL; | 3943 | struct sockaddr_in6 *addr6 = NULL; |
3938 | unsigned short snum; | 3944 | unsigned short snum; |
@@ -3959,8 +3965,9 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3959 | 3965 | ||
3960 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3966 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3961 | ad.selinux_audit_data = &sad; | 3967 | ad.selinux_audit_data = &sad; |
3962 | ad.u.net.dport = htons(snum); | 3968 | ad.u.net = &net; |
3963 | ad.u.net.family = sk->sk_family; | 3969 | ad.u.net->dport = htons(snum); |
3970 | ad.u.net->family = sk->sk_family; | ||
3964 | err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); | 3971 | err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); |
3965 | if (err) | 3972 | if (err) |
3966 | goto out; | 3973 | goto out; |
@@ -4050,11 +4057,13 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, | |||
4050 | struct sk_security_struct *sksec_new = newsk->sk_security; | 4057 | struct sk_security_struct *sksec_new = newsk->sk_security; |
4051 | struct common_audit_data ad; | 4058 | struct common_audit_data ad; |
4052 | struct selinux_audit_data sad = {0,}; | 4059 | struct selinux_audit_data sad = {0,}; |
4060 | struct lsm_network_audit net = {0,}; | ||
4053 | int err; | 4061 | int err; |
4054 | 4062 | ||
4055 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4063 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4056 | ad.selinux_audit_data = &sad; | 4064 | ad.selinux_audit_data = &sad; |
4057 | ad.u.net.sk = other; | 4065 | ad.u.net = &net; |
4066 | ad.u.net->sk = other; | ||
4058 | 4067 | ||
4059 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, | 4068 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, |
4060 | sksec_other->sclass, | 4069 | sksec_other->sclass, |
@@ -4082,10 +4091,12 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
4082 | struct sk_security_struct *osec = other->sk->sk_security; | 4091 | struct sk_security_struct *osec = other->sk->sk_security; |
4083 | struct common_audit_data ad; | 4092 | struct common_audit_data ad; |
4084 | struct selinux_audit_data sad = {0,}; | 4093 | struct selinux_audit_data sad = {0,}; |
4094 | struct lsm_network_audit net = {0,}; | ||
4085 | 4095 | ||
4086 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4096 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4087 | ad.selinux_audit_data = &sad; | 4097 | ad.selinux_audit_data = &sad; |
4088 | ad.u.net.sk = other->sk; | 4098 | ad.u.net = &net; |
4099 | ad.u.net->sk = other->sk; | ||
4089 | 4100 | ||
4090 | return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, | 4101 | return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, |
4091 | &ad); | 4102 | &ad); |
@@ -4122,12 +4133,14 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4122 | u32 sk_sid = sksec->sid; | 4133 | u32 sk_sid = sksec->sid; |
4123 | struct common_audit_data ad; | 4134 | struct common_audit_data ad; |
4124 | struct selinux_audit_data sad = {0,}; | 4135 | struct selinux_audit_data sad = {0,}; |
4136 | struct lsm_network_audit net = {0,}; | ||
4125 | char *addrp; | 4137 | char *addrp; |
4126 | 4138 | ||
4127 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4139 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4128 | ad.selinux_audit_data = &sad; | 4140 | ad.selinux_audit_data = &sad; |
4129 | ad.u.net.netif = skb->skb_iif; | 4141 | ad.u.net = &net; |
4130 | ad.u.net.family = family; | 4142 | ad.u.net->netif = skb->skb_iif; |
4143 | ad.u.net->family = family; | ||
4131 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4144 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
4132 | if (err) | 4145 | if (err) |
4133 | return err; | 4146 | return err; |
@@ -4155,6 +4168,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4155 | u32 sk_sid = sksec->sid; | 4168 | u32 sk_sid = sksec->sid; |
4156 | struct common_audit_data ad; | 4169 | struct common_audit_data ad; |
4157 | struct selinux_audit_data sad = {0,}; | 4170 | struct selinux_audit_data sad = {0,}; |
4171 | struct lsm_network_audit net = {0,}; | ||
4158 | char *addrp; | 4172 | char *addrp; |
4159 | u8 secmark_active; | 4173 | u8 secmark_active; |
4160 | u8 peerlbl_active; | 4174 | u8 peerlbl_active; |
@@ -4180,8 +4194,9 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4180 | 4194 | ||
4181 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4195 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4182 | ad.selinux_audit_data = &sad; | 4196 | ad.selinux_audit_data = &sad; |
4183 | ad.u.net.netif = skb->skb_iif; | 4197 | ad.u.net = &net; |
4184 | ad.u.net.family = family; | 4198 | ad.u.net->netif = skb->skb_iif; |
4199 | ad.u.net->family = family; | ||
4185 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4200 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
4186 | if (err) | 4201 | if (err) |
4187 | return err; | 4202 | return err; |
@@ -4517,6 +4532,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4517 | u32 peer_sid; | 4532 | u32 peer_sid; |
4518 | struct common_audit_data ad; | 4533 | struct common_audit_data ad; |
4519 | struct selinux_audit_data sad = {0,}; | 4534 | struct selinux_audit_data sad = {0,}; |
4535 | struct lsm_network_audit net = {0,}; | ||
4520 | u8 secmark_active; | 4536 | u8 secmark_active; |
4521 | u8 netlbl_active; | 4537 | u8 netlbl_active; |
4522 | u8 peerlbl_active; | 4538 | u8 peerlbl_active; |
@@ -4535,8 +4551,9 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4535 | 4551 | ||
4536 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4552 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4537 | ad.selinux_audit_data = &sad; | 4553 | ad.selinux_audit_data = &sad; |
4538 | ad.u.net.netif = ifindex; | 4554 | ad.u.net = &net; |
4539 | ad.u.net.family = family; | 4555 | ad.u.net->netif = ifindex; |
4556 | ad.u.net->family = family; | ||
4540 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) | 4557 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) |
4541 | return NF_DROP; | 4558 | return NF_DROP; |
4542 | 4559 | ||
@@ -4624,6 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4624 | struct sk_security_struct *sksec; | 4641 | struct sk_security_struct *sksec; |
4625 | struct common_audit_data ad; | 4642 | struct common_audit_data ad; |
4626 | struct selinux_audit_data sad = {0,}; | 4643 | struct selinux_audit_data sad = {0,}; |
4644 | struct lsm_network_audit net = {0,}; | ||
4627 | char *addrp; | 4645 | char *addrp; |
4628 | u8 proto; | 4646 | u8 proto; |
4629 | 4647 | ||
@@ -4633,8 +4651,9 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4633 | 4651 | ||
4634 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4652 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4635 | ad.selinux_audit_data = &sad; | 4653 | ad.selinux_audit_data = &sad; |
4636 | ad.u.net.netif = ifindex; | 4654 | ad.u.net = &net; |
4637 | ad.u.net.family = family; | 4655 | ad.u.net->netif = ifindex; |
4656 | ad.u.net->family = family; | ||
4638 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) | 4657 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) |
4639 | return NF_DROP; | 4658 | return NF_DROP; |
4640 | 4659 | ||
@@ -4657,6 +4676,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4657 | struct sock *sk; | 4676 | struct sock *sk; |
4658 | struct common_audit_data ad; | 4677 | struct common_audit_data ad; |
4659 | struct selinux_audit_data sad = {0,}; | 4678 | struct selinux_audit_data sad = {0,}; |
4679 | struct lsm_network_audit net = {0,}; | ||
4660 | char *addrp; | 4680 | char *addrp; |
4661 | u8 secmark_active; | 4681 | u8 secmark_active; |
4662 | u8 peerlbl_active; | 4682 | u8 peerlbl_active; |
@@ -4704,8 +4724,9 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4704 | 4724 | ||
4705 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 4725 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4706 | ad.selinux_audit_data = &sad; | 4726 | ad.selinux_audit_data = &sad; |
4707 | ad.u.net.netif = ifindex; | 4727 | ad.u.net = &net; |
4708 | ad.u.net.family = family; | 4728 | ad.u.net->netif = ifindex; |
4729 | ad.u.net->family = family; | ||
4709 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) | 4730 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) |
4710 | return NF_DROP; | 4731 | return NF_DROP; |
4711 | 4732 | ||
diff --git a/security/smack/smack.h b/security/smack/smack.h index ccba3823d9ef..4ede719922ed 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -325,6 +325,14 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, | |||
325 | a->a.smack_audit_data->function = func; | 325 | a->a.smack_audit_data->function = func; |
326 | } | 326 | } |
327 | 327 | ||
328 | static inline void smk_ad_init_net(struct smk_audit_info *a, const char *func, | ||
329 | char type, struct lsm_network_audit *net) | ||
330 | { | ||
331 | smk_ad_init(a, func, type); | ||
332 | memset(net, 0, sizeof(*net)); | ||
333 | a->a.u.net = net; | ||
334 | } | ||
335 | |||
328 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | 336 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, |
329 | struct task_struct *t) | 337 | struct task_struct *t) |
330 | { | 338 | { |
@@ -348,7 +356,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, | |||
348 | static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, | 356 | static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, |
349 | struct sock *sk) | 357 | struct sock *sk) |
350 | { | 358 | { |
351 | a->a.u.net.sk = sk; | 359 | a->a.u.net->sk = sk; |
352 | } | 360 | } |
353 | 361 | ||
354 | #else /* no AUDIT */ | 362 | #else /* no AUDIT */ |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index cd667b4089a5..81c03a597112 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1939,16 +1939,17 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) | |||
1939 | char *hostsp; | 1939 | char *hostsp; |
1940 | struct socket_smack *ssp = sk->sk_security; | 1940 | struct socket_smack *ssp = sk->sk_security; |
1941 | struct smk_audit_info ad; | 1941 | struct smk_audit_info ad; |
1942 | struct lsm_network_audit net; | ||
1942 | 1943 | ||
1943 | rcu_read_lock(); | 1944 | rcu_read_lock(); |
1944 | hostsp = smack_host_label(sap); | 1945 | hostsp = smack_host_label(sap); |
1945 | if (hostsp != NULL) { | 1946 | if (hostsp != NULL) { |
1946 | sk_lbl = SMACK_UNLABELED_SOCKET; | 1947 | sk_lbl = SMACK_UNLABELED_SOCKET; |
1947 | #ifdef CONFIG_AUDIT | 1948 | #ifdef CONFIG_AUDIT |
1948 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 1949 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
1949 | ad.a.u.net.family = sap->sin_family; | 1950 | ad.a.u.net->family = sap->sin_family; |
1950 | ad.a.u.net.dport = sap->sin_port; | 1951 | ad.a.u.net->dport = sap->sin_port; |
1951 | ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; | 1952 | ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; |
1952 | #endif | 1953 | #endif |
1953 | rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); | 1954 | rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); |
1954 | } else { | 1955 | } else { |
@@ -2808,9 +2809,10 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
2808 | struct socket_smack *osp = other->sk_security; | 2809 | struct socket_smack *osp = other->sk_security; |
2809 | struct socket_smack *nsp = newsk->sk_security; | 2810 | struct socket_smack *nsp = newsk->sk_security; |
2810 | struct smk_audit_info ad; | 2811 | struct smk_audit_info ad; |
2812 | struct lsm_network_audit net; | ||
2811 | int rc = 0; | 2813 | int rc = 0; |
2812 | 2814 | ||
2813 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 2815 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
2814 | smk_ad_setfield_u_net_sk(&ad, other); | 2816 | smk_ad_setfield_u_net_sk(&ad, other); |
2815 | 2817 | ||
2816 | if (!capable(CAP_MAC_OVERRIDE)) | 2818 | if (!capable(CAP_MAC_OVERRIDE)) |
@@ -2840,9 +2842,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) | |||
2840 | struct socket_smack *ssp = sock->sk->sk_security; | 2842 | struct socket_smack *ssp = sock->sk->sk_security; |
2841 | struct socket_smack *osp = other->sk->sk_security; | 2843 | struct socket_smack *osp = other->sk->sk_security; |
2842 | struct smk_audit_info ad; | 2844 | struct smk_audit_info ad; |
2845 | struct lsm_network_audit net; | ||
2843 | int rc = 0; | 2846 | int rc = 0; |
2844 | 2847 | ||
2845 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 2848 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
2846 | smk_ad_setfield_u_net_sk(&ad, other->sk); | 2849 | smk_ad_setfield_u_net_sk(&ad, other->sk); |
2847 | 2850 | ||
2848 | if (!capable(CAP_MAC_OVERRIDE)) | 2851 | if (!capable(CAP_MAC_OVERRIDE)) |
@@ -2990,6 +2993,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
2990 | char *csp; | 2993 | char *csp; |
2991 | int rc; | 2994 | int rc; |
2992 | struct smk_audit_info ad; | 2995 | struct smk_audit_info ad; |
2996 | struct lsm_network_audit net; | ||
2993 | if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) | 2997 | if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) |
2994 | return 0; | 2998 | return 0; |
2995 | 2999 | ||
@@ -3007,9 +3011,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3007 | netlbl_secattr_destroy(&secattr); | 3011 | netlbl_secattr_destroy(&secattr); |
3008 | 3012 | ||
3009 | #ifdef CONFIG_AUDIT | 3013 | #ifdef CONFIG_AUDIT |
3010 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 3014 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
3011 | ad.a.u.net.family = sk->sk_family; | 3015 | ad.a.u.net->family = sk->sk_family; |
3012 | ad.a.u.net.netif = skb->skb_iif; | 3016 | ad.a.u.net->netif = skb->skb_iif; |
3013 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); | 3017 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); |
3014 | #endif | 3018 | #endif |
3015 | /* | 3019 | /* |
@@ -3152,6 +3156,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3152 | char *sp; | 3156 | char *sp; |
3153 | int rc; | 3157 | int rc; |
3154 | struct smk_audit_info ad; | 3158 | struct smk_audit_info ad; |
3159 | struct lsm_network_audit net; | ||
3155 | 3160 | ||
3156 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ | 3161 | /* handle mapped IPv4 packets arriving via IPv6 sockets */ |
3157 | if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) | 3162 | 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 | netlbl_secattr_destroy(&secattr); | 3171 | netlbl_secattr_destroy(&secattr); |
3167 | 3172 | ||
3168 | #ifdef CONFIG_AUDIT | 3173 | #ifdef CONFIG_AUDIT |
3169 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); | 3174 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
3170 | ad.a.u.net.family = family; | 3175 | ad.a.u.net->family = family; |
3171 | ad.a.u.net.netif = skb->skb_iif; | 3176 | ad.a.u.net->netif = skb->skb_iif; |
3172 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); | 3177 | ipv4_skb_to_auditdata(skb, &ad.a, NULL); |
3173 | #endif | 3178 | #endif |
3174 | /* | 3179 | /* |