From c750e6929d3c76d13d1d0ba475989d6dd74785d5 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Fri, 12 Apr 2019 19:59:34 +0900 Subject: [PATCH] selinux: Check address length before reading address family KMSAN will complain if valid address length passed to bind()/connect() is shorter than sizeof("struct sockaddr"->sa_family) bytes. Signed-off-by: Tetsuo Handa Signed-off-by: Paul Moore --- security/selinux/hooks.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d5fdcb0d26fe..c61787b15f27 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4512,7 +4512,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; - u16 family_sa = address->sa_family; + u16 family_sa; unsigned short snum; u32 sid, node_perm; @@ -4522,6 +4522,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in * need to check address->sa_family as it is possible to have * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. */ + if (addrlen < offsetofend(struct sockaddr, sa_family)) + return -EINVAL; + family_sa = address->sa_family; switch (family_sa) { case AF_UNSPEC: case AF_INET: @@ -4654,6 +4657,8 @@ static int selinux_socket_connect_helper(struct socket *sock, * need to check address->sa_family as it is possible to have * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. */ + if (addrlen < offsetofend(struct sockaddr, sa_family)) + return -EINVAL; switch (address->sa_family) { case AF_INET: addr4 = (struct sockaddr_in *)address;