Commit e5f54bcd1e for qemu.org

commit e5f54bcd1e00db76e670aaa5ac25fd11303f2490
Author: Filip Hejsek <filip.hejsek@gmail.com>
Date:   Mon Oct 12 19:38:14 2026 +0200

    io: avoid potential double close of qio_channel_file's fd

    Make qio_channel_file_close() set fd to -1 even if qemu_close() returns
    an error so that qio_channel_file_finalize() doesn't call close again.

    On Linux, close() always closes the fd, even when it returns an error.
    Because the fd can be reused after it is closed, the close must not
    be retried.

    Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
    Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
    Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>

diff --git a/io/channel-file.c b/io/channel-file.c
index 4c9da6619b..2487adaea2 100644
--- a/io/channel-file.c
+++ b/io/channel-file.c
@@ -261,12 +261,24 @@ static int qio_channel_file_close(QIOChannel *ioc,
 {
     QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);

-    if (qemu_close(fioc->fd) < 0) {
+    int ret = qemu_close(fioc->fd);
+    /*
+     * Set fioc->fd to -1, to prevent qio_channel_file_finalize() from
+     * closing it again.
+     *
+     * POSIX.1-2024 specifies that the fd is closed even when close()
+     * returns an error, except when the error is EINTR.  The systems that
+     * QEMU supports however violate the standard and always close the fd,
+     * even when returning EINTR.  If the fd was actually closed, we must not
+     * try to close it a second time as we could accidentally close someone
+     * else's fd.
+     */
+    fioc->fd = -1;
+    if (ret < 0) {
         error_setg_errno(errp, errno,
-                         "Unable to close file");
+                         "Got an error while closing file");
         return -1;
     }
-    fioc->fd = -1;
     return 0;
 }