On Thu, Dec 04, 2025 at 19:22:12 -0000, nikolaus@rath.org wrote:
Hello,
I'm puzzled by how libvirtd manages access control.
As far as I can tell, on my Fedora system it runs qemu and virtiofsd instances as user qemu. Yet, the qemu process apparently has read/write access to storage devices in /dev that only root has rw access for. Similarly, virtiofsd is able to write into shared directories that the qemu user does not have access to (confirmed by switching to qemu user with sudo).
What is libvirtd (or virt-manager) doing to make this work?
For entries in /dev/ libvirt creates a separate mount namespace for the qemu process to run in and then adds all nodes which the VM definition points to (the XML). These are then chown'd to 'qemu' user so that the qemu process has access to it. All of that without modifying the host /dev/. In case mount namespaces are disabled you'd see some node files to be chown'd to qemu. Files in the regular filesystem are chown'd to the qemu user, so they should be accessible. In the "system" (qemu:///system) privileged instance of libvirt 'virtiofsd' still runs as root IIRC because it also wants to to be able to honour UID changes from the guest on the host. In the unprivileged instance uid mapping can be used to map users from the VM to the host.
Then, as far as I can tell, there's lots of sockets with different permissions created by systemd in /run/libvirt (e.g. libvirt-admin-sock, libvirt-sock, libvirt-sock-ro). But since they're all passed to libvirtd as open file descriptors, I don't understand how they can give different levels of access (since libvirtd has no way of knowing which socket was used).
Libvirt actually does know what socket you've used to connect to it and actually also knows the UID of the connecting client. This allows filtering access on a granular level with our ACL support.