]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuFDPassLogFDInfo: Check if FD is valid before 'fstat'-ing it
authorPeter Krempa <pkrempa@redhat.com>
Mon, 18 May 2026 08:38:12 +0000 (10:38 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 25 May 2026 11:28:57 +0000 (13:28 +0200)
Some test cases (qemuxmlconftest) currently use made up descriptors,
which cause e.g. valgrind to be unhappy:

 ==831186== File descriptor 1729 Invalid file descriptor
 ==831186==    at 0x531042E: fgetxattr (in /usr/lib64/libc.so.6)
 ==831186==    by 0x5AE2846: ??? (in /usr/lib64/libselinux.so.1)
 ==831186==    by 0x5AE7093: fgetfilecon_raw (in /usr/lib64/libselinux.so.1)
 ==831186==    by 0x4EB736F: qemuFDPassLogFDInfo (qemu_fd.c:92)
 ==831186==    by 0x4EB7B8E: qemuFDPassDirectTransferCommand (qemu_fd.c:443)

when tracking FDs. Since 'qemuFDPassLogFDInfo' just logs information
about the FD we can simply not query the FD if it's made up.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_fd.c

index ef0a8d812789611ba4ddd9c7ee812ff7a49ccbef..8c8b6afcfde3244b438d54ec657ebe33a785bfce 100644 (file)
@@ -25,6 +25,8 @@
 #include "virfile.h"
 #include "virlog.h"
 
+#include <fcntl.h>
+
 /* Used strictly for logging selinux context of passed FD */
 #ifdef WITH_SECDRIVER_SELINUX
 # include <selinux/selinux.h>
@@ -59,40 +61,43 @@ qemuFDPassLogFDInfo(const char *name,
     g_autofree char *selinux = NULL;
     g_autofree char *tmp = NULL;
 
-    if (fstat(fd, &st) == 0) {
-        switch (st.st_mode & S_IFMT) {
-           case S_IFBLK:
-               type = "block";
-               break;
-           case S_IFCHR:
-               type = "char";
-               break;
-           case S_IFDIR:
-               type = "directory";
-               break;
-           case S_IFIFO:
-               type = "pipe";
-               break;
-           case S_IFLNK:
-               type = "symlink";
-               break;
-           case S_IFREG:
-               type = "file";
-               break;
-           case S_IFSOCK:
-               type = "socket";
-               break;
-           default:
-               type = tmp = g_strdup_printf("unknown:'0x%x')", st.st_mode & S_IFMT);
-               break;
+    if (fcntl(fd, F_GETFD) != -1) {
+        if (fstat(fd, &st) == 0) {
+            switch (st.st_mode & S_IFMT) {
+            case S_IFBLK:
+                type = "block";
+                break;
+            case S_IFCHR:
+                type = "char";
+                break;
+            case S_IFDIR:
+                type = "directory";
+                break;
+            case S_IFIFO:
+                type = "pipe";
+                break;
+            case S_IFLNK:
+                type = "symlink";
+                break;
+            case S_IFREG:
+                type = "file";
+                break;
+            case S_IFSOCK:
+                type = "socket";
+                break;
+            default:
+                type = tmp = g_strdup_printf("unknown:'0x%x')", st.st_mode & S_IFMT);
+                break;
+            }
         }
-    }
 
 #ifdef WITH_SECDRIVER_SELINUX
-    ignore_value(fgetfilecon_raw(fd, &selinux));
-#else
-    selinux = g_strdup("N/A");
+        ignore_value(fgetfilecon_raw(fd, &selinux));
 #endif
+    }
+
+    if (!selinux)
+        selinux = g_strdup("N/A");
 
     VIR_DEBUG("passing fd:'%i', name:'%s'(%zu) type:'%s' selinux:'%s'",
               fd, name, idx, type, selinux);