Commit b9ef5513 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by Casey Schaufler

smack: Check address length before reading address family

KMSAN will complain if valid address length passed to bind()/connect()/
sendmsg() is shorter than sizeof("struct sockaddr"->sa_family) bytes.

Also, since smk_ipv6_port_label()/smack_netlabel_send()/
smack_ipv6host_label()/smk_ipv6_check()/smk_ipv6_port_check() are not
checking valid address length and/or address family, make sure we check
both. The minimal valid length in smack_socket_connect() is changed from
sizeof(struct sockaddr_in6) bytes to SIN6_LEN_RFC2133 bytes, for it seems
that Smack is not using "struct sockaddr_in6"->sin6_scope_id field.
Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
parent f7450bc6
...@@ -2806,13 +2806,17 @@ static int smack_socket_socketpair(struct socket *socka, ...@@ -2806,13 +2806,17 @@ static int smack_socket_socketpair(struct socket *socka,
* *
* Records the label bound to a port. * Records the label bound to a port.
* *
* Returns 0 * Returns 0 on success, and error code otherwise
*/ */
static int smack_socket_bind(struct socket *sock, struct sockaddr *address, static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
int addrlen) int addrlen)
{ {
if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
if (addrlen < SIN6_LEN_RFC2133 ||
address->sa_family != AF_INET6)
return -EINVAL;
smk_ipv6_port_label(sock, address); smk_ipv6_port_label(sock, address);
}
return 0; return 0;
} }
#endif /* SMACK_IPV6_PORT_LABELING */ #endif /* SMACK_IPV6_PORT_LABELING */
...@@ -2848,12 +2852,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, ...@@ -2848,12 +2852,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
switch (sock->sk->sk_family) { switch (sock->sk->sk_family) {
case PF_INET: case PF_INET:
if (addrlen < sizeof(struct sockaddr_in)) if (addrlen < sizeof(struct sockaddr_in) ||
sap->sa_family != AF_INET)
return -EINVAL; return -EINVAL;
rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
break; break;
case PF_INET6: case PF_INET6:
if (addrlen < sizeof(struct sockaddr_in6)) if (addrlen < SIN6_LEN_RFC2133 || sap->sa_family != AF_INET6)
return -EINVAL; return -EINVAL;
#ifdef SMACK_IPV6_SECMARK_LABELING #ifdef SMACK_IPV6_SECMARK_LABELING
rsp = smack_ipv6host_label(sip); rsp = smack_ipv6host_label(sip);
...@@ -3683,9 +3688,15 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -3683,9 +3688,15 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
switch (sock->sk->sk_family) { switch (sock->sk->sk_family) {
case AF_INET: case AF_INET:
if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
sip->sin_family != AF_INET)
return -EINVAL;
rc = smack_netlabel_send(sock->sk, sip); rc = smack_netlabel_send(sock->sk, sip);
break; break;
case AF_INET6: case AF_INET6:
if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
sap->sin6_family != AF_INET6)
return -EINVAL;
#ifdef SMACK_IPV6_SECMARK_LABELING #ifdef SMACK_IPV6_SECMARK_LABELING
rsp = smack_ipv6host_label(sap); rsp = smack_ipv6host_label(sap);
if (rsp != NULL) if (rsp != NULL)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment