[PATCH 2/3] smack: Check address length before reading address family
Casey Schaufler
casey at schaufler-ca.com
Fri Apr 12 15:32:17 UTC 2019
On 4/12/2019 3:59 AM, Tetsuo Handa wrote:
> 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: Tetsuo Handa <penguin-kernel at I-love.SAKURA.ne.jp>
Acked-by: Casey Schaufler <casey at schaufler-ca.com>
> ---
> security/smack/smack_lsm.c | 19 +++++++++++++++----
> 1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 5c1613519d5a..4b59e4519e0c 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -2805,13 +2805,17 @@ static int smack_socket_socketpair(struct socket *socka,
> *
> * 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,
> 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);
> + }
> return 0;
> }
> #endif /* SMACK_IPV6_PORT_LABELING */
> @@ -2847,12 +2851,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
>
> switch (sock->sk->sk_family) {
> case PF_INET:
> - if (addrlen < sizeof(struct sockaddr_in))
> + if (addrlen < sizeof(struct sockaddr_in) ||
> + sap->sa_family != AF_INET)
> return -EINVAL;
> rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
> break;
> case PF_INET6:
> - if (addrlen < sizeof(struct sockaddr_in6))
> + if (addrlen < SIN6_LEN_RFC2133 || sap->sa_family != AF_INET6)
> return -EINVAL;
> #ifdef SMACK_IPV6_SECMARK_LABELING
> rsp = smack_ipv6host_label(sip);
> @@ -3682,9 +3687,15 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
>
> switch (sock->sk->sk_family) {
> 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);
> break;
> case AF_INET6:
> + if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
> + sap->sin6_family != AF_INET6)
> + return -EINVAL;
> #ifdef SMACK_IPV6_SECMARK_LABELING
> rsp = smack_ipv6host_label(sap);
> if (rsp != NULL)
More information about the Linux-security-module-archive
mailing list