diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 337fb325e5cc..e7eaef2ea021 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4517,22 +4517,29 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4517 | * need to check address->sa_family as it is possible to have | 4517 | * need to check address->sa_family as it is possible to have |
4518 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4518 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
4519 | */ | 4519 | */ |
4520 | if (address->sa_family == AF_INET) { | 4520 | switch (address->sa_family) { |
4521 | if (addrlen < sizeof(struct sockaddr_in)) { | 4521 | case AF_INET: |
4522 | err = -EINVAL; | 4522 | if (addrlen < sizeof(struct sockaddr_in)) |
4523 | goto out; | 4523 | return -EINVAL; |
4524 | } | ||
4525 | addr4 = (struct sockaddr_in *)address; | 4524 | addr4 = (struct sockaddr_in *)address; |
4526 | snum = ntohs(addr4->sin_port); | 4525 | snum = ntohs(addr4->sin_port); |
4527 | addrp = (char *)&addr4->sin_addr.s_addr; | 4526 | addrp = (char *)&addr4->sin_addr.s_addr; |
4528 | } else { | 4527 | break; |
4529 | if (addrlen < SIN6_LEN_RFC2133) { | 4528 | case AF_INET6: |
4530 | err = -EINVAL; | 4529 | if (addrlen < SIN6_LEN_RFC2133) |
4531 | goto out; | 4530 | return -EINVAL; |
4532 | } | ||
4533 | addr6 = (struct sockaddr_in6 *)address; | 4531 | addr6 = (struct sockaddr_in6 *)address; |
4534 | snum = ntohs(addr6->sin6_port); | 4532 | snum = ntohs(addr6->sin6_port); |
4535 | addrp = (char *)&addr6->sin6_addr.s6_addr; | 4533 | addrp = (char *)&addr6->sin6_addr.s6_addr; |
4534 | break; | ||
4535 | default: | ||
4536 | /* Note that SCTP services expect -EINVAL, whereas | ||
4537 | * others expect -EAFNOSUPPORT. | ||
4538 | */ | ||
4539 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
4540 | return -EINVAL; | ||
4541 | else | ||
4542 | return -EAFNOSUPPORT; | ||
4536 | } | 4543 | } |
4537 | 4544 | ||
4538 | if (snum) { | 4545 | if (snum) { |
@@ -4636,16 +4643,27 @@ static int selinux_socket_connect_helper(struct socket *sock, | |||
4636 | * need to check address->sa_family as it is possible to have | 4643 | * need to check address->sa_family as it is possible to have |
4637 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4644 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
4638 | */ | 4645 | */ |
4639 | if (address->sa_family == AF_INET) { | 4646 | switch (address->sa_family) { |
4647 | case AF_INET: | ||
4640 | addr4 = (struct sockaddr_in *)address; | 4648 | addr4 = (struct sockaddr_in *)address; |
4641 | if (addrlen < sizeof(struct sockaddr_in)) | 4649 | if (addrlen < sizeof(struct sockaddr_in)) |
4642 | return -EINVAL; | 4650 | return -EINVAL; |
4643 | snum = ntohs(addr4->sin_port); | 4651 | snum = ntohs(addr4->sin_port); |
4644 | } else { | 4652 | break; |
4653 | case AF_INET6: | ||
4645 | addr6 = (struct sockaddr_in6 *)address; | 4654 | addr6 = (struct sockaddr_in6 *)address; |
4646 | if (addrlen < SIN6_LEN_RFC2133) | 4655 | if (addrlen < SIN6_LEN_RFC2133) |
4647 | return -EINVAL; | 4656 | return -EINVAL; |
4648 | snum = ntohs(addr6->sin6_port); | 4657 | snum = ntohs(addr6->sin6_port); |
4658 | break; | ||
4659 | default: | ||
4660 | /* Note that SCTP services expect -EINVAL, whereas | ||
4661 | * others expect -EAFNOSUPPORT. | ||
4662 | */ | ||
4663 | if (sksec->sclass == SECCLASS_SCTP_SOCKET) | ||
4664 | return -EINVAL; | ||
4665 | else | ||
4666 | return -EAFNOSUPPORT; | ||
4649 | } | 4667 | } |
4650 | 4668 | ||
4651 | err = sel_netport_sid(sk->sk_protocol, snum, &sid); | 4669 | err = sel_netport_sid(sk->sk_protocol, snum, &sid); |