diff options
author | Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> | 2019-04-12 13:59:34 +0300 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-04-15 19:42:06 +0300 |
commit | c750e6929d3c76d13d1d0ba475989d6dd74785d5 (patch) | |
tree | 359f0254a7f431ce565de023339b2ee3e8cf6be4 | |
parent | 1537ad15c9c59ce852748578eb5633139053e86b (diff) | |
download | linux-c750e6929d3c76d13d1d0ba475989d6dd74785d5.tar.xz |
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 <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | security/selinux/hooks.c | 7 |
1 files changed, 6 insertions, 1 deletions
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; |