aports/main/libuv/recvmmsg-padding.patch
Ariadne Conill c70367d409 main/libuv: fix padding when calling recvmmsg(3)
libc verses kernel structure layout differences caused the structure
to not be properly initialized in all cases (namely s390x)

noticed by @alxu
2022-01-20 22:38:44 +00:00

64 lines
2.3 KiB
Diff

From e9cb18484ecdc10e005d306db53d099e06ade9f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@sury.org>
Date: Sat, 15 Jan 2022 06:24:37 +0100
Subject: [PATCH] unix: ensure struct msghdr is zeroed in recvmmsg (#3419)
With MUSL libc, the struct msghdr is padded to align with the types used
in the Linux kernel headers (int vs size_t). When the padding was not
zeroed, the syscall would return EMSGSIZE because the random bytes in
the padding would be read by kernel as part of the size_t type.
Fixes: https://github.com/libuv/libuv/issues/3416
---
src/unix/udp.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/unix/udp.c b/src/unix/udp.c
index aee8d63934..74ef398a06 100644
--- a/src/unix/udp.c
+++ b/src/unix/udp.c
@@ -201,6 +201,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
for (k = 0; k < chunks; ++k) {
iov[k].iov_base = buf->base + k * UV__UDP_DGRAM_MAXSIZE;
iov[k].iov_len = UV__UDP_DGRAM_MAXSIZE;
+ memset(&msgs[k].msg_hdr, 0, sizeof(msgs[k].msg_hdr));
msgs[k].msg_hdr.msg_iov = iov + k;
msgs[k].msg_hdr.msg_iovlen = 1;
msgs[k].msg_hdr.msg_name = peers + k;
@@ -655,16 +656,16 @@ int uv__udp_connect(uv_udp_t* handle,
}
/* From https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
- * Any of uv supported UNIXs kernel should be standardized, but the kernel
+ * Any of uv supported UNIXs kernel should be standardized, but the kernel
* implementation logic not same, let's use pseudocode to explain the udp
* disconnect behaviors:
- *
+ *
* Predefined stubs for pseudocode:
* 1. sodisconnect: The function to perform the real udp disconnect
* 2. pru_connect: The function to perform the real udp connect
* 3. so: The kernel object match with socket fd
* 4. addr: The sockaddr parameter from user space
- *
+ *
* BSDs:
* if(sodisconnect(so) == 0) { // udp disconnect succeed
* if (addr->sa_len != so->addr->sa_len) return EINVAL;
@@ -694,13 +695,13 @@ int uv__udp_disconnect(uv_udp_t* handle) {
#endif
memset(&addr, 0, sizeof(addr));
-
+
#if defined(__MVS__)
addr.ss_family = AF_UNSPEC;
#else
addr.sa_family = AF_UNSPEC;
#endif
-
+
do {
errno = 0;
r = connect(handle->io_watcher.fd, (struct sockaddr*) &addr, sizeof(addr));