See how libvirt compares to other vendors in security performance
A file permission vulnerability was found in libvirt's storage volume clone/convert path in src/storage/storageutil.c. The virStorageBackendCreateExecCommand() function ran qemu-img with umask 0 on non-NETFS local storage paths, causing newly created volume images to be world-readable (mode 0644) during the copy operation. libvirt only tightened the file permissions via chmod() after qemu-img completed, creating a window where the full guest disk contents could be read by any local user.
This is the same class of issue as CVE-2025-13193. A local attacker could exploit this race window to read sensitive guest disk contents, resulting in information disclosure.
The fix moves the virCommandSetUmask() call to apply unconditionally to all code paths, ensuring qemu-img creates files with restrictive permissions from the outset.
Upstream fix: https://gitlab.com/libvirt/libvirt/-/commit/69335a484768d550854da1133d5490074695e825
A symlink-following vulnerability was found in libvirt's virFileChownFiles() function in src/util/virfile.c. This function is called from src/qemu/qemutpm.c to change ownership of the swtpm state directory when starting a QEMU domain.
The function used stat() (via virFileIsRegular()) and chown(), both of which follow symlinks. A process running as the confined swtpm user (tss) can plant a symlink inside the swtpm state directory pointing to an arbitrary file. When the root-level libvirt daemon starts the next domain, it calls virFileChownFiles() which follows the symlink and chowns the target file to the tss user. This allows escalation from the swtpm sandbox to root-level file ownership control.
The fix replaces stat()/chown() with lstat()/lchown() to avoid following symlinks on the final path component.
Upstream fix: https://gitlab.com/libvirt/libvirt/-/commit/801160fd414ca2cc402bc01ead09b7ed4c3b8f5b
A flaw was found in libvirt. The network XML parser accepts XML numeric character references for line breaks ( / ) in DNS TXT record value attributes and SRV record domain/target attributes without sanitization. The network driver writes these values directly into the line-oriented dnsmasq configuration file as txt-record= or srv-host= directives. An embedded newline terminates the intended directive and begins a new one under attacker control (e.g., dhcp-script=/bin/sh -c '<cmd>'), which dnsmasq executes as root when the virtual network is started. Under the default libvirt deployment model, read-write access to the libvirt socket is already root-equivalent, and the <dnsmasq:options> raw namespace already provides a documented mechanism for arbitrary directive injection, making this a hardening issue only. However, under non-default polkit fine-grained access control configurations that grant only network.write and network.start permissions, this could represent a privilege boundary violation.
A flaw was found in libvirt. The network XML parser accepts XML numeric character references for line breaks ( / ) in DNS TXT record value attributes and SRV record domain/target attributes without sanitization. The network driver writes these values directly into the line-oriented dnsmasq configuration file as txt-record= or srv-host= directives. An embedded newline terminates the intended directive and begins a new one under attacker control (e.g., dhcp-script=/bin/sh -c '<cmd>'), which dnsmasq executes as root when the virtual network is started. Under the default libvirt deployment model, read-write access to the libvirt socket is already root-equivalent, and the <dnsmasq:options> raw namespace already provides a documented mechanism for arbitrary directive injection, making this a hardening issue only. However, under non-default polkit fine-grained access control configurations that grant only network.write and network.start permissions, this could represent a privilege boundary violation.
External inactive snapshots for shut-down VMs are incorrectly created as world-readable, making it possible for unprivileged users to inspect the guest OS contents. This results in an information disclosure vulnerability.
Debian bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1120119
Upstream patch: https://gitlab.com/libvirt/libvirt/-/commit/a379327d8abcde8ac8d3e16fe5e4ba6f790d767a
A flaw was discovered in libvirt in the XML file processing. More specifically, the parsing of user provided XML files was performed before the ACL checks (https://libvirt.org/acl.html). A malicious user with limited permissions could exploit this flaw by submitting a specially crafted XML file, causing libvirt to allocate too much memory on the host. The excessive memory consumption could lead to a libvirt process crash on the host, resulting in a denial-of-service condition.
Upstream issue: https://gitlab.com/libvirt/libvirt/-/issues/825
Patch: https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/LTGHU3S4JEMCF5KJNJGWWZ7F2CS6L5SG/
A flaw was discovered in libvirt in the XML file processing. More specifically, the parsing of user provided XML files was performed before the ACL checks (https://libvirt.org/acl.html). A malicious user with limited permissions could exploit this flaw by submitting a specially crafted XML file, causing libvirt to allocate too much memory on the host. The excessive memory consumption could lead to a libvirt process crash on the host, resulting in a denial-of-service condition.
Upstream issue: https://gitlab.com/libvirt/libvirt/-/issues/825
Patch: https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/LTGHU3S4JEMCF5KJNJGWWZ7F2CS6L5SG/
A flaw was found in libvirt. External inactive snapshots for shut-down VMs are incorrectly created as world-readable, making it possible for unprivileged users to inspect the guest OS contents. This results in an information disclosure vulnerability.
A refactor of the code fetching the list of interfaces for multiple APIs introduced a corner case on platforms where allocating 0 bytes of memory results in a NULL pointer.
This corner case would lead to a NULL-pointer dereference and subsequent crash of virtinterfaced if virConnectListInterfaces() is called requesting 0 networks to be filled.
The bug was introduced in libvirt-10.4.0 and reproduces only on platforms where allocation of 0-length memory returns NULL instead of a valid pointer.
Upstream fix: https://gitlab.com/libvirt/libvirt/-/commit/8dfb12cb77996519901b8d52c754ab564ebd10e8
A race condition leading to a stack use-after-free bug was found in libvirt. Due to a bad assumption in the virNetClientIOEventLoop() method, the data pointer to a stack-allocated virNetClientIOEventData structure ended up being used in virNetClientIOEventFD callback while the data pointer's stack frame was concurrently being "freed" when returning from virNetClientIOEventLoop().
Quoting libvirt maintainer Daniel P. Berrangé: The 'virtproxyd' daemon can be used to trigger requests which could potentially exercise the bug. If libvirt is configured with fine grained access control, this could in theory let a user escape their otherwise limited access. A local unprivileged user can access virtproxyd without authenticating. Remote users would need to authenticate before they could exercise it.
A flaw was found in the RPC library APIs of libvirt. The RPC server de-serialization code allocates memory for arrays before the non-negative length check is performed by the C API entry points. Passing a negative length to the gnew0 function results in a crash due to the negative length being treated as a huge positive number. A local unprivileged user could use this flaw to perform a denial of service attack by causing the libvirt daemon to crash.
A flaw was found in the libvirt virStoragePoolLookupByTargetPath API. The storagePoolLookupByTargetPath() function does not properly release a locked object (virStoragePoolObj) on ACL permission failure. Clients connecting to the read-write socket with limited ACL permissions could use this flaw to acquire the lock and prevent other users from accessing storage pool/volume APIs, resulting in a denial of service condition.
Upstream fix: https://libvirt.org/git/?p=libvirt.git;a=commit;h=447f69dec47e1b0bd15ecd7cd49a9fd3b050fb87
A vulnerability was found in libvirt, where an incorrect permissions on the UNIX domain socket. A local attacker could use this issue to access libvirt and escalate privileges.
References: https://bugs.mageia.org/27038
A vulnerability was found in libvirt >= 4.1.0 in the virtlockd-admin.socket and virtlogd-admin.socket systemd units. A missing SocketMode configuration parameter allows any user on the host to connect using virtlockd-admin-sock or virtlogd-admin-sock and perform administrative tasks against the virtlockd and virtlogd daemons.
It was reported that the libvirt daemon using RBD leaks ceph key/id in the process list:
As a non-privileged user you can run ps -ef | grep libvirt and see the below output. In this you can see libvirt using the ceph key as part of the command to run the VM. In particular this section
~~~ -drive file=rbd:mgmt/os-network:id=libvirt:key=AQA/H4dUwLYnORAAhWv2E+67eN72ue3rrl2klg==:authsupported=cephx none,if=none,id=drive-virtio-disk0,format=raw,cache=writeback ~~~
With the 'id' and 'key' values, any user can perform any operations on the cluster which that key provides. Typically, that would be the ability to create/delete RBDs within the cinder pool.
Full output: ~~~ qemu 13924 1 33 Dec10 ? 2-23:31:12 /usr/libexec/qemu-kvm -S -M rhel6.1.0 -enable-kvm -m 8000 -smp 8,sockets=8,cores=1,threads=1 -name os-network -uuid f0ede7e8-c15a-4813-900e-971988d494c1 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/os-network.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=rbd:mgmt/os-network:id=libvirt:key=AQA/H4dUwLYnORAAhWv2E+67eN72ue3rrl2klg==:authsupported=cephx none,if=none,id=drive-virtio-disk0,format=raw,cache=writeback -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x9,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=21,id=hostnet0,vhost=on,vhostfd=27 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:64:92:b6,bus=pci.0,addr=0x3 -netdev tap,fd=28,id=hostnet1,vhost=on,vhostfd=29 -device virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:f7:50:e2,bus=pci.0,addr=0x4 -netdev tap,fd=30,id=hostnet2,vhost=on,vhostfd=31 -device virtio-net-pci,netdev=hostnet2,id=net2,mac=52:54:00:14:3b:33,bus=pci.0,addr=0x5 -netdev tap,fd=32,id=hostnet3,vhost=on,vhostfd=33 -device virtio-net-pci,netdev=hostnet3,id=net3,mac=52:54:00:fd:86:aa,bus=pci.0,addr=0x6 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc 127.0.0.1:5 -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x8 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 ~~~
It was reported that the libvirt daemon using RBD leaks ceph key/id in the process list:
As a non-privileged user you can run ps -ef | grep libvirt and see the below output. In this you can see libvirt using the ceph key as part of the command to run the VM. In particular this section
~~~ -drive file=rbd:mgmt/os-network:id=libvirt:key=AQA/H4dUwLYnORAAhWv2E+67eN72ue3rrl2klg==:authsupported=cephx none,if=none,id=drive-virtio-disk0,format=raw,cache=writeback ~~~
With the 'id' and 'key' values, any user can perform any operations on the cluster which that key provides. Typically, that would be the ability to create/delete RBDs within the cinder pool.
Full output: ~~~ qemu 13924 1 33 Dec10 ? 2-23:31:12 /usr/libexec/qemu-kvm -S -M rhel6.1.0 -enable-kvm -m 8000 -smp 8,sockets=8,cores=1,threads=1 -name os-network -uuid f0ede7e8-c15a-4813-900e-971988d494c1 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/os-network.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive file=rbd:mgmt/os-network:id=libvirt:key=AQA/H4dUwLYnORAAhWv2E+67eN72ue3rrl2klg==:authsupported=cephx none,if=none,id=drive-virtio-disk0,format=raw,cache=writeback -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x9,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -netdev tap,fd=21,id=hostnet0,vhost=on,vhostfd=27 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:64:92:b6,bus=pci.0,addr=0x3 -netdev tap,fd=28,id=hostnet1,vhost=on,vhostfd=29 -device virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:f7:50:e2,bus=pci.0,addr=0x4 -netdev tap,fd=30,id=hostnet2,vhost=on,vhostfd=31 -device virtio-net-pci,netdev=hostnet2,id=net2,mac=52:54:00:14:3b:33,bus=pci.0,addr=0x5 -netdev tap,fd=32,id=hostnet3,vhost=on,vhostfd=33 -device virtio-net-pci,netdev=hostnet3,id=net3,mac=52:54:00:fd:86:aa,bus=pci.0,addr=0x6 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0 -vnc 127.0.0.1:5 -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x8 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 ~~~
The virDomainListPopulate function in conf/domainconf.c in libvirt before 1.2.9 does not clean up the lock on the list of domains, which allows remote attackers to cause a denial of service (deadlock) via a NULL value in the second parameter in the virConnectListAllDomains API command.
The qemuDomainGetBlockIoTune function in qemu/qemudriver.c in libvirt before 1.2.9, when a disk has been hot-plugged or removed from the live image, allows remote attackers to cause a denial of service (crash) or read sensitive heap information via a crafted blkiotune query, which triggers an out-of-bounds read.
An invalid free flaw in the libxl driver in libvirt resulted in libvirt crashing if "virsh numatune" was run on an inactive domain. It may be possible, but unlikely, for an attacker to leverage this flaw for arbitrary code execution.
This issue affects the version of libvirt in Fedora 20. It does not affect the versions of libvirt in Red Hat Enterprise Linux 5 and 6 as those versions do not use libxl.
A flaw was found in libvirt where libvirtd could crash due to how XML was parsed [1]. With the introduction of ACL permissions in libvirt 1.1.0, this flaw could be manipulated to allow a remote user with connect:read privileges to elevate them to the more permissive domain:write privilege.
This vulnerability was introduced in libvirt 1.1.0.
[1] https://bugzilla.redhat.com/showbug.cgi?id=1012196;
Upstream Commit 29fe5d7 (released in 1.1.1) introduced a latent problem for any caller of virSecurityManagerSetProcessLabel and where the domain already had a uid:gid label to be parsed. Such a setup would collect the list of supplementary groups during virSecurityManagerPreFork, but then ignores that information, and thus fails to call setgroups() to adjust the supplementary groups of the process.
Introduced by: http://libvirt.org/git/?p=libvirt.git;a=commit;h=29fe5d745fbe207ec2415441d4807ae76be05974
Upstream fix: http://libvirt.org/git/?p=libvirt.git;a=commit;h=fe11d34a6d46d6641ce90dc665164fda7bb6bff8
Commit 632180d1 introduced memory corruption in xenDaemonListDefinedDomains() by starting to populate the names array at index -1, causing all sorts of havoc in libvirtd such as aborts like the following
Error in /usr/sbin/libvirtd': double free or corruption (out): 0x00007fffe00ccf20
The xenDaemonListDefinedDomains() function is reached by the virConnectListDefinedDomains() public API, which can be used on read-only connections.
Introduced in: libvirt v1.1.1
Introduced by: http://libvirt.org/git/?p=libvirt.git;a=commit;h=632180d1
Fixed by: http://libvirt.org/git/?p=libvirt.git;a=commit;h=0e671a16
Daniel P. Berrange reported:
"As non-root, simply run:
# virsh -c qemu:///system --readonly iface-list --inactive
The libvirtd daemon will crash with one of a number of different stack traces, for example:
Error in /home/berrange/src/virt/libvirt/daemon/.libs/lt-libvirtd': invalid fastbin entry (free): 0x00007f03fc02a1b0 ======= Backtrace: ========= /lib64/libc.so.6(+0x3cd5e7cef8)[0x7f0425cf7ef8] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virFree+0x2e)[0x7f04293fd79e] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virLogVMessage+0x37d)[0x7f042942384d] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virLogMessage+0x97)[0x7f0429423b27] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virObjectUnref+0x65)[0x7f04294324d5] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virIdentitySetCurrent+0x35)[0x7f042941ae25] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virNetServerProgramDispatch+0x392)[0x7f0429539be2] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(+0x195d68)[0x7f0429533d68] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(+0xa62e5)[0x7f04294442e5] /home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(+0xa594e)[0x7f042944394e] /lib64/libpthread.so.0(+0x3cd6207c53)[0x7f0426449c53] /lib64/libc.so.6(clone+0x6d)[0x7f0425d6fecd]
Looking at the code, we have a double-free of the 'struct netcfif' object when any of the filtering flags are set. Hence this only happens if you pass '--inactive' to virsh."
Upstream fix:
http://libvirt.org/git/?p=libvirt.git;a=commit;h=244e0b8cf15ca2ef48d82058e728656e6c4bad11
Acknowledgements:
This issue was discovered by Daniel P. Berrange of Red Hat.
Description of problem: On my workstation, as a virtual machine host, I have NetworkManager's dnsmasq configured to forward DNS queries for a local domain to 192.168.122.1, so I can resolve those to virtual machine DHCP hostnames. Recently this stopped working.
With manual dig commands, I found that TCP queries still work, but UDP doesn't. For example, in libvirt I have a statically defined name "vhost" to 192.168.122.1 itself. From the host, the command "dig +short +tcp @192.168.122.1 vhost" resolves that just fine. But "dig +short +notcp @192.168.122.1 vhost" says "connection timed out; no servers could be reached". From a guest, +tcp and +notcp both work fine.
Version-Release number of selected component (if applicable): libvirt-0.9.11.8-2.fc17.x8664, dnsmasq-2.63-1.fc17.x8664 I also tried dnsmasq-2.65-1.fc17.x8664 from updates-testing
How reproducible: 100%
Steps to Reproduce: 1. From the virtual machine host, try to query the libvirt dnsmasq. Actual results: $ dig +short +tcp @192.168.122.1 vhost 192.168.122.1 $ dig +short +notcp @192.168.122.1 vhost ;; connection timed out; no servers could be reached
Expected results: A positive answer from both TCP and UDP queries.
Additional info: I suspect this is related to the fixes for CVE-2012-3411, but it seems weird that UDP and TCP would be treated differently.
It was found that libvirt did not explicitly set the user defined backing store format when creating new image. This results in images being created with an potentialy insecure configuration, preventing applications from opening backing stores without resorting to probing. A priviledged guest user could use this flaw to access arbitrary files on the host.
It was found that libvirt did not explicitly set the user defined backing store format when creating new image. This results in images being created with an potentialy insecure configuration, preventing applications from opening backing stores without resorting to probing. A priviledged guest user could use this flaw to access arbitrary files on the host.
It was found that libvirt did not extract the defined disk backing store format when recursing into disk image backing stores in the security drivers. This could be possibly exploited by priviledged guest user to access arbitrary files on the host.
It was found that libvirt did not extract the defined disk backing store format when recursing into disk image backing stores in the security drivers. This could be possibly exploited by priviledged guest user to access arbitrary files on the host.
It was found that libvirt did not honour the user defined main disk format in guest XML when looking up disk backing stores in the security drivers. This could be possibly exploited by priviledged guest user to access arbitrary files on the host.
It was found that libvirt did not honour the user defined main disk format in guest XML when looking up disk backing stores in the security drivers. This could be possibly exploited by priviledged guest user to access arbitrary files on the host.