summary refs log tree commit diff stats
path: root/io/channel-socket.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-09-19 12:20:43 -0700
committerRichard Henderson <richard.henderson@linaro.org>2025-09-19 12:20:43 -0700
commitcaf2e8de4ed056acad4fbdb6fe420d8124d38f11 (patch)
tree13e664b2b7577724ad773621478e47221dbba5cc /io/channel-socket.c
parente7c1e8043a69c5a8efa39d4f9d111f7c72c076e6 (diff)
parent34523df31962401871ff091a9d0993ac87a9848a (diff)
downloadfocaccia-qemu-caf2e8de4ed056acad4fbdb6fe420d8124d38f11.tar.gz
focaccia-qemu-caf2e8de4ed056acad4fbdb6fe420d8124d38f11.zip
Merge tag 'misc-fixes-pull-request' of https://gitlab.com/berrange/qemu into staging
 * Update security triage contact address
 * Check and honour failures to the blocking flag on FDs
 * Don't touch blocking flags on FDs received during migration

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE2vOm/bJrYpEtDo4/vobrtBUQT98FAmjNQuAACgkQvobrtBUQ
# T99xaBAAr6zQPii1tjzuzLovF6MIqtldXnmVO/yjcl5NgLWonIRDt2JsxnRxi3es
# 9uNDed5+ePNXmUAYd46k81gBEjBWbv465kt5FHAZZV6BRw/PPzkoh+jzGc8NVir8
# 3GZJ2kPr51PxGEl8md2vRthg4bMuhlS5ogCEqAMDYT4f6AVemfnNQ5NttGX353T2
# etxoMhEeMtTBKjMoTBv+SVhhO4nKwZ+6CFhvuGON423EfrGlkNTXyprKTdzpr4i0
# 4KDQLxxoANlmg/1W0PxfrLiBCmGpHweMR44Piv715VYa2YNPRq0G6EC6AFGbHZ51
# N+mKmWNE0CS5rP1TEacSCX4q6If5VxjSLLj+og8LmpIlJ6tiqdrisSqA6bzCJ1f/
# lMsfUsKoMqPhqat9ZGUkYu8REgKP+O+CSGJNftYTsEEY0oKZrAW4fsoN3E9qpfcG
# Xy6eSu0TTGDWE6CEe0vkHiQwlVHMtRcWMSPwlsvrgt2TO6k97reT3AoIBK2VfygC
# WzMv0P0nBvHFKeIbqmFOk3BEI5+JECgxVRc1WXWbSFLW0PBY/xd7g6ow8uaQsd9e
# pzMA1Pwh2EuM4DTlOy+m9zBOhm9YP9An188NLldOne3TFKFYe5QO1DQpvvEGvIGB
# +4XpmyOj3g2ycelZZ5XsDJk0LumCCOcbSPSiAvHZyWwLo24EABE=
# =rrMd
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 19 Sep 2025 04:47:44 AM PDT
# gpg:                using RSA key DAF3A6FDB26B62912D0E8E3FBE86EBB415104FDF
# gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>" [unknown]
# gpg:                 aka "Daniel P. Berrange <berrange@redhat.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E  8E3F BE86 EBB4 1510 4FDF

* tag 'misc-fixes-pull-request' of https://gitlab.com/berrange/qemu:
  util/vhost-user-server: vu_message_read(): improve error handling
  chardev: close an fd on failure path
  chardev: qemu_chr_open_fd(): add errp
  treewide: use qemu_set_blocking instead of g_unix_set_fd_nonblocking
  util: drop qemu_socket_set_block()
  io/channel-socket: rework qio_channel_socket_copy_fds()
  util: drop qemu_socket_try_set_nonblock()
  util: drop qemu_socket_set_nonblock()
  migration: qemu_file_set_blocking(): add errp parameter
  treewide: handle result of qio_channel_set_blocking()
  util: add qemu_set_blocking() function
  char-socket: tcp_chr_recv(): add comment
  char-socket: tcp_chr_recv(): drop extra _set_(block,cloexec)
  io/channel: document how qio_channel_readv_full() handles fds
  migration/qemu-file: don't make incoming fds blocking again
  MAINTAINERS: list qemu-security@nongnu.org as security contact

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'io/channel-socket.c')
-rw-r--r--io/channel-socket.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 3b7ca924ff..e53d9ac76f 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -472,7 +472,7 @@ static void qio_channel_socket_copy_fds(struct msghdr *msg,
     *fds = NULL;
 
     for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
-        int fd_size, i;
+        int fd_size;
         int gotfds;
 
         if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) ||
@@ -490,22 +490,53 @@ static void qio_channel_socket_copy_fds(struct msghdr *msg,
         gotfds = fd_size / sizeof(int);
         *fds = g_renew(int, *fds, *nfds + gotfds);
         memcpy(*fds + *nfds, CMSG_DATA(cmsg), fd_size);
+        *nfds += gotfds;
+    }
+}
 
-        for (i = 0; i < gotfds; i++) {
-            int fd = (*fds)[*nfds + i];
-            if (fd < 0) {
-                continue;
-            }
+static bool qio_channel_handle_fds(int *fds, size_t nfds,
+                                   bool preserve_blocking, Error **errp)
+{
+    int *end = fds + nfds, *fd;
 
+#ifdef MSG_CMSG_CLOEXEC
+    if (preserve_blocking) {
+        /* Nothing to do */
+        return true;
+    }
+#endif
+
+    for (fd = fds; fd != end; fd++) {
+        if (*fd < 0) {
+            continue;
+        }
+
+        if (!preserve_blocking) {
             /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
-            qemu_socket_set_block(fd);
+            if (!qemu_set_blocking(*fd, true, errp)) {
+                return false;
+            }
+        }
 
 #ifndef MSG_CMSG_CLOEXEC
-            qemu_set_cloexec(fd);
+        qemu_set_cloexec(*fd);
 #endif
+    }
+
+    return true;
+}
+
+static void qio_channel_cleanup_fds(int **fds, size_t *nfds)
+{
+    for (size_t i = 0; i < *nfds; i++) {
+        if ((*fds)[i] < 0) {
+            continue;
         }
-        *nfds += gotfds;
+        close((*fds)[i]);
     }
+
+    g_clear_pointer(fds, g_free);
+    *nfds = 0;
 }
 
 
@@ -556,7 +587,16 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
     }
 
     if (fds && nfds) {
+        bool preserve_blocking =
+            flags & QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING;
+
         qio_channel_socket_copy_fds(&msg, fds, nfds);
+
+        if (!qio_channel_handle_fds(*fds, *nfds,
+                                    preserve_blocking, errp)) {
+            qio_channel_cleanup_fds(fds, nfds);
+            return -1;
+        }
     }
 
     return ret;
@@ -820,11 +860,10 @@ qio_channel_socket_set_blocking(QIOChannel *ioc,
 {
     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
 
-    if (enabled) {
-        qemu_socket_set_block(sioc->fd);
-    } else {
-        qemu_socket_set_nonblock(sioc->fd);
+    if (!qemu_set_blocking(sioc->fd, enabled, errp)) {
+        return -1;
     }
+
     return 0;
 }