Daniel Berrange discovered that libvirt fails to check whether connection to libvirtd is in read-only or read-write mode, possibly allowing non-privileged users with access to the host machine to perform certain actions that should be restricted to administrative users only.
The following methods in libvirt.c are missing a check against the read-only connection flag:
virDomainMigrate virDomainMigratePrepare virDomainMigratePerform virDomainMigrateFinish virDomainMigratePrepare2 virDomainMigrateFinish2 virDomainBlockPeek virDomainMemoryPeek virDomainSetAutostart virNetworkSetAutostart virConnectFindStoragePoolSources virStoragePoolSetAutostart
In recent versions, libvirt uses PolicyKit to authorize connections from users. Default policy allows any local user to connect in the read-only mode.
Older versions of libvirt, or version not compiled with PolicyKit or with PolicyKit authorization disabled, default to allow read-only connections to all local users.
Thus out of the box unprivileged local users may be able to migrate VMs, set or unset the autostart flag for domains, networks & storage pools, and access privileged data in the VM memory, or disks.
All TCP remote connections are read-write, and fully authenticated, thus not impacted.
Jeremy Nickurak reported an issue with how libvirt creates iptables rules when guest systems are setup for masquerading. The iptables rule will be of the following format:
iptables-save -t nat Generated by iptables-save v1.4.7 on Wed Jun 9 14:59:03 2010 nat :PREROUTING ACCEPT [45:5146] :POSTROUTING ACCEPT [889:54117] :OUTPUT ACCEPT [889:54117] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE COMMIT Completed on Wed Jun 9 14:59:03 2010
With masquerading, outgoing connections will have their source-port mapped to a NAT-selected port, and the iptables default is for privileged ports to be mapped to privileged (<1024) ports.
This will allow users in guests that have root privileges (in the guest, independent of their privileges on the host), to obtain privileged resources on the host, as well as being able to access other resources by using it. One example is with standard NFS exports now being accessible to the guests, because the guests will appear to be from the same IP as a possibly trusted host.
To illustrate:
regular-user@host-machine:~$ ssh guest-machine Last login: Wed Jun 9 11:33:13 2010 from host-machine regular-user@guest-machine:~$ sudo mount -t nfs -o udp,rw,soft remote-nfs-server:/some-export /mnt/tmp
(get UID of resources on the remote NFS server, and create a user in the guest with that UID> (su to that new UID)
user-with-same-uid@guest-machine:~$ cp -R /mnt/tmp/secret-data /home/mycopy; rm -Rf /mnt/tmp/secret-data
A normal user account would not normally be able to do something like this because they cannot bind to the privileged port, however in this case the NAT rules permits it.
An example modified set of iptables rules that may solve the problem was supplied as well:
/sbin/iptables -t nat -A POSTROUTING -p tcp -o $(IFACE) -j MASQUERADE --to-ports 1024-65535 /sbin/iptables -t nat -A POSTROUTING -p udp -o $(IFACE) -j MASQUERADE --to-ports 1024-65535 /sbin/iptables -t nat -A POSTROUTING -p icmp -o $(IFACE) -j MASQUERADE
The above uses the --to-ports option that forces iptables' masquerading module to only map guest reqursts to non-privileged ports.
Acknowledgements:
Red Hat would like to thank Jeremy Nickurak for reporting this issue.