diff options
author | David S. Miller <davem@davemloft.net> | 2018-05-21 16:01:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-21 16:01:54 -0400 |
commit | 6f6e434aa267a6030477876d89444fe3a6b7a48d (patch) | |
tree | 67755c422f1e85451aa646eae21d4c6f3f389d9f /security/selinux/hooks.c | |
parent | 44c752fe584d8b9f6e0756ecffa8691677471862 (diff) | |
parent | 6741c4bb389da103c0d79ad1961884628900bfe6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
S390 bpf_jit.S is removed in net-next and had changes in 'net',
since that code isn't used any more take the removal.
TLS data structures split the TX and RX components in 'net-next',
put the new struct members from the bug fix in 'net' into the RX
part.
The 'net-next' tree had some reworking of how the ERSPAN code works in
the GRE tunneling code, overlapping with a one-line headroom
calculation fix in 'net'.
Overlapping changes in __sock_map_ctx_update_elem(), keep the bits
that read the prog members via READ_ONCE() into local variables
before using them.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5c508d26b367..6bd9358e5e62 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4578,6 +4578,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, | |||
4578 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) | 4578 | static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) |
4579 | { | 4579 | { |
4580 | struct sock *sk = sock->sk; | 4580 | struct sock *sk = sock->sk; |
4581 | struct sk_security_struct *sksec = sk->sk_security; | ||
4581 | u16 family; | 4582 | u16 family; |
4582 | int err; | 4583 | int err; |
4583 | 4584 | ||
@@ -4589,11 +4590,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4589 | family = sk->sk_family; | 4590 | family = sk->sk_family; |
4590 | if (family == PF_INET || family == PF_INET6) { | 4591 | if (family == PF_INET || family == PF_INET6) { |
4591 | char *addrp; | 4592 | char *addrp; |
4592 | struct sk_security_struct *sksec = sk->sk_security; | ||
4593 | struct common_audit_data ad; | 4593 | struct common_audit_data ad; |
4594 | struct lsm_network_audit net = {0,}; | 4594 | struct lsm_network_audit net = {0,}; |
4595 | struct sockaddr_in *addr4 = NULL; | 4595 | struct sockaddr_in *addr4 = NULL; |
4596 | struct sockaddr_in6 *addr6 = NULL; | 4596 | struct sockaddr_in6 *addr6 = NULL; |
4597 | u16 family_sa = address->sa_family; | ||
4597 | unsigned short snum; | 4598 | unsigned short snum; |
4598 | u32 sid, node_perm; | 4599 | u32 sid, node_perm; |
4599 | 4600 | ||
@@ -4603,11 +4604,20 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4603 | * need to check address->sa_family as it is possible to have | 4604 | * need to check address->sa_family as it is possible to have |
4604 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4605 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
4605 | */ | 4606 | */ |
4606 | switch (address->sa_family) { | 4607 | switch (family_sa) { |
4608 | case AF_UNSPEC: | ||
4607 | case AF_INET: | 4609 | case AF_INET: |
4608 | if (addrlen < sizeof(struct sockaddr_in)) | 4610 | if (addrlen < sizeof(struct sockaddr_in)) |
4609 | return -EINVAL; | 4611 | return -EINVAL; |
4610 | addr4 = (struct sockaddr_in *)address; | 4612 | addr4 = (struct sockaddr_in *)address; |
4613 | if (family_sa == AF_UNSPEC) { | ||
4614 | /* see __inet_bind(), we only want to allow | ||
4615 | * AF_UNSPEC if the address is INADDR_ANY | ||
4616 | */ | ||
4617 | if (addr4->sin_addr.s_addr != htonl(INADDR_ANY)) | ||
4618 | goto err_af; | ||
4619 | family_sa = AF_INET; | ||
4620 | } | ||
4611 | snum = ntohs(addr4->sin_port); | 4621 | snum = ntohs(addr4->sin_port); |
4612 | addrp = (char *)&addr4->sin_addr.s_addr; | 4622 | addrp = (char *)&addr4->sin_addr.s_addr; |
4613 | break; | 4623 | break; |
@@ -4619,15 +4629,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4619 | addrp = (char *)&addr6->sin6_addr.s6_addr; | 4629 | addrp = (char *)&addr6->sin6_addr.s6_addr; |
4620 | break; | 4630 | break; |
4621 | default: | 4631 | default: |
4622 | /* Note that SCTP services expect -EINVAL, whereas | 4632 | goto err_af; |
4623 | * others expect -EAFNOSUPPORT. | ||
4624 | */ | ||
4625 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
4626 | return -EINVAL; | ||
4627 | else | ||
4628 | return -EAFNOSUPPORT; | ||
4629 | } | 4633 | } |
4630 | 4634 | ||
4635 | ad.type = LSM_AUDIT_DATA_NET; | ||
4636 | ad.u.net = &net; | ||
4637 | ad.u.net->sport = htons(snum); | ||
4638 | ad.u.net->family = family_sa; | ||
4639 | |||
4631 | if (snum) { | 4640 | if (snum) { |
4632 | int low, high; | 4641 | int low, high; |
4633 | 4642 | ||
@@ -4639,10 +4648,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4639 | snum, &sid); | 4648 | snum, &sid); |
4640 | if (err) | 4649 | if (err) |
4641 | goto out; | 4650 | goto out; |
4642 | ad.type = LSM_AUDIT_DATA_NET; | ||
4643 | ad.u.net = &net; | ||
4644 | ad.u.net->sport = htons(snum); | ||
4645 | ad.u.net->family = family; | ||
4646 | err = avc_has_perm(&selinux_state, | 4651 | err = avc_has_perm(&selinux_state, |
4647 | sksec->sid, sid, | 4652 | sksec->sid, sid, |
4648 | sksec->sclass, | 4653 | sksec->sclass, |
@@ -4674,16 +4679,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4674 | break; | 4679 | break; |
4675 | } | 4680 | } |
4676 | 4681 | ||
4677 | err = sel_netnode_sid(addrp, family, &sid); | 4682 | err = sel_netnode_sid(addrp, family_sa, &sid); |
4678 | if (err) | 4683 | if (err) |
4679 | goto out; | 4684 | goto out; |
4680 | 4685 | ||
4681 | ad.type = LSM_AUDIT_DATA_NET; | 4686 | if (family_sa == AF_INET) |
4682 | ad.u.net = &net; | ||
4683 | ad.u.net->sport = htons(snum); | ||
4684 | ad.u.net->family = family; | ||
4685 | |||
4686 | if (address->sa_family == AF_INET) | ||
4687 | ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; | 4687 | ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; |
4688 | else | 4688 | else |
4689 | ad.u.net->v6info.saddr = addr6->sin6_addr; | 4689 | ad.u.net->v6info.saddr = addr6->sin6_addr; |
@@ -4696,6 +4696,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4696 | } | 4696 | } |
4697 | out: | 4697 | out: |
4698 | return err; | 4698 | return err; |
4699 | err_af: | ||
4700 | /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */ | ||
4701 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
4702 | return -EINVAL; | ||
4703 | return -EAFNOSUPPORT; | ||
4699 | } | 4704 | } |
4700 | 4705 | ||
4701 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) | 4706 | /* This supports connect(2) and SCTP connect services such as sctp_connectx(3) |
@@ -4773,7 +4778,7 @@ static int selinux_socket_connect_helper(struct socket *sock, | |||
4773 | ad.type = LSM_AUDIT_DATA_NET; | 4778 | ad.type = LSM_AUDIT_DATA_NET; |
4774 | ad.u.net = &net; | 4779 | ad.u.net = &net; |
4775 | ad.u.net->dport = htons(snum); | 4780 | ad.u.net->dport = htons(snum); |
4776 | ad.u.net->family = sk->sk_family; | 4781 | ad.u.net->family = address->sa_family; |
4777 | err = avc_has_perm(&selinux_state, | 4782 | err = avc_has_perm(&selinux_state, |
4778 | sksec->sid, sid, sksec->sclass, perm, &ad); | 4783 | sksec->sid, sid, sksec->sclass, perm, &ad); |
4779 | if (err) | 4784 | if (err) |
@@ -5274,6 +5279,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
5274 | while (walk_size < addrlen) { | 5279 | while (walk_size < addrlen) { |
5275 | addr = addr_buf; | 5280 | addr = addr_buf; |
5276 | switch (addr->sa_family) { | 5281 | switch (addr->sa_family) { |
5282 | case AF_UNSPEC: | ||
5277 | case AF_INET: | 5283 | case AF_INET: |
5278 | len = sizeof(struct sockaddr_in); | 5284 | len = sizeof(struct sockaddr_in); |
5279 | break; | 5285 | break; |
@@ -5281,7 +5287,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
5281 | len = sizeof(struct sockaddr_in6); | 5287 | len = sizeof(struct sockaddr_in6); |
5282 | break; | 5288 | break; |
5283 | default: | 5289 | default: |
5284 | return -EAFNOSUPPORT; | 5290 | return -EINVAL; |
5285 | } | 5291 | } |
5286 | 5292 | ||
5287 | err = -EINVAL; | 5293 | err = -EINVAL; |