diff options
| author | Mateusz Jurczyk <mjurczyk@google.com> | 2017-06-08 05:13:36 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-06-09 10:10:24 -0400 |
| commit | defbcf2decc903a28d8398aa477b6881e711e3ea (patch) | |
| tree | e347eafc099d97c7570f56124209c90a5ebca176 /net/unix | |
| parent | fc5b775da468e359154795afeb27be79b509b76d (diff) | |
af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers
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>
Diffstat (limited to 'net/unix')
| -rw-r--r-- | net/unix/af_unix.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 6a7fe7660551..1a0c961f4ffe 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -999,7 +999,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 999 | struct path path = { }; | 999 | struct path path = { }; |
| 1000 | 1000 | ||
| 1001 | err = -EINVAL; | 1001 | err = -EINVAL; |
| 1002 | if (sunaddr->sun_family != AF_UNIX) | 1002 | if (addr_len < offsetofend(struct sockaddr_un, sun_family) || |
| 1003 | sunaddr->sun_family != AF_UNIX) | ||
| 1003 | goto out; | 1004 | goto out; |
| 1004 | 1005 | ||
| 1005 | if (addr_len == sizeof(short)) { | 1006 | if (addr_len == sizeof(short)) { |
| @@ -1110,6 +1111,10 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, | |||
| 1110 | unsigned int hash; | 1111 | unsigned int hash; |
| 1111 | int err; | 1112 | int err; |
| 1112 | 1113 | ||
| 1114 | err = -EINVAL; | ||
| 1115 | if (alen < offsetofend(struct sockaddr, sa_family)) | ||
| 1116 | goto out; | ||
| 1117 | |||
| 1113 | if (addr->sa_family != AF_UNSPEC) { | 1118 | if (addr->sa_family != AF_UNSPEC) { |
| 1114 | err = unix_mkname(sunaddr, alen, &hash); | 1119 | err = unix_mkname(sunaddr, alen, &hash); |
| 1115 | if (err < 0) | 1120 | if (err < 0) |
