Blame 0001-qemu-sockets-fix-unix-socket-path-copy-again.patch

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 */