|
|
1d93f5 |
From 118d527f2e4baec5fe8060b22a6212468b8e4d3f Mon Sep 17 00:00:00 2001
|
|
|
1d93f5 |
From: Michael Tokarev <mjt@tls.msk.ru>
|
|
|
1d93f5 |
Date: Wed, 1 Sep 2021 16:16:24 +0300
|
|
|
1d93f5 |
Subject: [PATCH] qemu-sockets: fix unix socket path copy (again)
|
|
|
1d93f5 |
MIME-Version: 1.0
|
|
|
1d93f5 |
Content-Type: text/plain; charset=UTF-8
|
|
|
1d93f5 |
Content-Transfer-Encoding: 8bit
|
|
|
1d93f5 |
|
|
|
1d93f5 |
Commit 4cfd970ec188558daa6214f26203fe553fb1e01f added an
|
|
|
1d93f5 |
assert which ensures the path within an address of a unix
|
|
|
1d93f5 |
socket returned from the kernel is at least one byte and
|
|
|
1d93f5 |
does not exceed sun_path buffer. Both of this constraints
|
|
|
1d93f5 |
are wrong:
|
|
|
1d93f5 |
|
|
|
1d93f5 |
A unix socket can be unnamed, in this case the path is
|
|
|
1d93f5 |
completely empty (not even \0)
|
|
|
1d93f5 |
|
|
|
1d93f5 |
And some implementations (notable linux) can add extra
|
|
|
1d93f5 |
trailing byte (\0) _after_ the sun_path buffer if we
|
|
|
1d93f5 |
passed buffer larger than it (and we do).
|
|
|
1d93f5 |
|
|
|
1d93f5 |
So remove the assertion (since it causes real-life breakage)
|
|
|
1d93f5 |
but at the same time fix the usage of sun_path. Namely,
|
|
|
1d93f5 |
we should not access sun_path[0] if kernel did not return
|
|
|
1d93f5 |
it at all (this is the case for unnamed sockets),
|
|
|
1d93f5 |
and use the returned salen when copyig actual path as an
|
|
|
1d93f5 |
upper constraint for the amount of bytes to copy - this
|
|
|
1d93f5 |
will ensure we wont exceed the information provided by
|
|
|
1d93f5 |
the kernel, regardless whenever there is a trailing \0
|
|
|
1d93f5 |
or not. This also helps with unnamed sockets.
|
|
|
1d93f5 |
|
|
|
1d93f5 |
Note the case of abstract socket, the sun_path is actually
|
|
|
1d93f5 |
a blob and can contain \0 characters, - it should not be
|
|
|
1d93f5 |
passed to g_strndup and the like, it should be accessed by
|
|
|
1d93f5 |
memcpy-like functions.
|
|
|
1d93f5 |
|
|
|
1d93f5 |
Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f
|
|
|
1d93f5 |
Fixes: http://bugs.debian.org/993145
|
|
|
1d93f5 |
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
|
|
1d93f5 |
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
1d93f5 |
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
|
|
1d93f5 |
CC: qemu-stable@nongnu.org
|
|
|
1d93f5 |
---
|
|
|
1d93f5 |
util/qemu-sockets.c | 13 +++++--------
|
|
|
1d93f5 |
1 file changed, 5 insertions(+), 8 deletions(-)
|
|
|
1d93f5 |
|
|
|
1d93f5 |
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
|
|
|
1d93f5 |
index f2f3676d1f..c5043999e9 100644
|
|
|
1d93f5 |
--- a/util/qemu-sockets.c
|
|
|
1d93f5 |
+++ b/util/qemu-sockets.c
|
|
|
1d93f5 |
@@ -1345,25 +1345,22 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
|
|
|
1d93f5 |
SocketAddress *addr;
|
|
|
1d93f5 |
struct sockaddr_un *su = (struct sockaddr_un *)sa;
|
|
|
1d93f5 |
|
|
|
1d93f5 |
- assert(salen >= sizeof(su->sun_family) + 1 &&
|
|
|
1d93f5 |
- salen <= sizeof(struct sockaddr_un));
|
|
|
1d93f5 |
-
|
|
|
1d93f5 |
addr = g_new0(SocketAddress, 1);
|
|
|
1d93f5 |
addr->type = SOCKET_ADDRESS_TYPE_UNIX;
|
|
|
1d93f5 |
+ salen -= offsetof(struct sockaddr_un, sun_path);
|
|
|
1d93f5 |
#ifdef CONFIG_LINUX
|
|
|
1d93f5 |
- if (!su->sun_path[0]) {
|
|
|
1d93f5 |
+ if (salen > 0 && !su->sun_path[0]) {
|
|
|
1d93f5 |
/* Linux abstract socket */
|
|
|
1d93f5 |
- addr->u.q_unix.path = g_strndup(su->sun_path + 1,
|
|
|
1d93f5 |
- salen - sizeof(su->sun_family) - 1);
|
|
|
1d93f5 |
+ addr->u.q_unix.path = g_strndup(su->sun_path + 1, salen - 1);
|
|
|
1d93f5 |
addr->u.q_unix.has_abstract = true;
|
|
|
1d93f5 |
addr->u.q_unix.abstract = true;
|
|
|
1d93f5 |
addr->u.q_unix.has_tight = true;
|
|
|
1d93f5 |
- addr->u.q_unix.tight = salen < sizeof(*su);
|
|
|
1d93f5 |
+ addr->u.q_unix.tight = salen < sizeof(su->sun_path);
|
|
|
1d93f5 |
return addr;
|
|
|
1d93f5 |
}
|
|
|
1d93f5 |
#endif
|
|
|
1d93f5 |
|
|
|
1d93f5 |
- addr->u.q_unix.path = g_strndup(su->sun_path, sizeof(su->sun_path));
|
|
|
1d93f5 |
+ addr->u.q_unix.path = g_strndup(su->sun_path, salen);
|
|
|
1d93f5 |
return addr;
|
|
|
1d93f5 |
}
|
|
|
1d93f5 |
#endif /* WIN32 */
|