summaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorMateusz Jurczyk <mjurczyk@google.com>2017-06-08 11:13:36 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-07-05 14:37:13 +0200
commit0fc0fad07722e7ff1e4322e2155b8cd4d963e42a (patch)
tree9053a49be4d06b7c2ac6c7d86d7d41b28c38da94 /net/unix
parente2c3ee003280ce0e6cd02f305dd6c1ced17f286c (diff)
downloadlinux-stable-0fc0fad07722e7ff1e4322e2155b8cd4d963e42a.tar.gz
linux-stable-0fc0fad07722e7ff1e4322e2155b8cd4d963e42a.tar.bz2
linux-stable-0fc0fad07722e7ff1e4322e2155b8cd4d963e42a.zip
af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers
[ Upstream commit defbcf2decc903a28d8398aa477b6881e711e3ea ] Verify that the caller-provided sockaddr structure is large enough to contain the sa_family field, before accessing it in bind() and connect() handlers of the AF_UNIX socket. Since neither syscall enforces a minimum size of the corresponding memory region, very short sockaddrs (zero or one byte long) result in operating on uninitialized memory while referencing .sa_family. Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index b2e934ff2448..e05ec54ac53f 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -997,7 +997,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct path path = { NULL, NULL };
err = -EINVAL;
- if (sunaddr->sun_family != AF_UNIX)
+ if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
+ sunaddr->sun_family != AF_UNIX)
goto out;
if (addr_len == sizeof(short)) {
@@ -1108,6 +1109,10 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
unsigned int hash;
int err;
+ err = -EINVAL;
+ if (alen < offsetofend(struct sockaddr, sa_family))
+ goto out;
+
if (addr->sa_family != AF_UNSPEC) {
err = unix_mkname(sunaddr, alen, &hash);
if (err < 0)