diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 105 |
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 | ||