aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2012-04-02 13:15:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-03 12:49:10 -0400
commit48c62af68a403ef1655546bd3e021070c8508573 (patch)
treeba938e4fb45d5bdaad2dad44071d0625f8e36945 /security/selinux
parent3b3b0e4fc15efa507b902d90cea39e496a523c3b (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>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c105
1 files changed, 63 insertions, 42 deletions
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