libkrun icon indicating copy to clipboard operation
libkrun copied to clipboard

Virtio-fs escape outside of specified vm directory

Open mtjhrc opened this issue 8 months ago • 1 comments

In the current form, it is possible to escape out of directories exposed by the libkruns "fs" device. In fact, there is even a warning in the source code: https://github.com/containers/libkrun/blob/9041aaa4cb7f80e463ed82ec3bf1a9301174217d/src/devices/src/virtio/fs/linux/passthrough.rs#L311-L316

But we don't provide any warning to the user here: https://github.com/containers/libkrun/blob/45563e9c78cdae42aad48d7633ea13941a21976c/include/libkrun.h#L61-L71

And here: https://github.com/containers/libkrun/blob/9041aaa4cb7f80e463ed82ec3bf1a9301174217d/include/libkrun.h#L198-L208

The main issue stems from the fact that we basically trust the guest kernel that when it gives us a filename it is actually a filename and not a path. In order to exploit this you need to modify the guest kernel, which should be possible within the VM since you have root access. This is because the normal user-space API obviously resolves path for you and doesn't allow you to attempt to create files with invalid names.

I made a patch for the libkrunfw kernel to play around with this from userspace: https://gist.github.com/mtjhrc/964e009b2a18e7f1b7311df4b7d8696d This hacky patch allows you to issue weird fs request from userspace with invalid "filenames" containing / and ... This changes % into / and :: into .. in virtio-fs requests.

I tested this on Linux host, but I think this should also be exploitable on macOS (with slightly different behavior).

I found 2 related variants of this bug:

  • putting a path with .. and / in filename of virtio-fs commands:

    Run this inside the VM to create a file named HACKED in your /tmp on the host filesystem: # touch ::%::%::%::%::%::%tmp%HACKED (The kernel patch changes this to ../../../../../../tmp/HACKED)

    The fix for this should be straight forward - refuse to process fs request from the guest with / in filenames in libkrun.

  • resolving .. of / I feel like this is slightly different than the first issue, because it could make sense for the guest to use .. to refer to parent directories that are still inside the VM directory (but I'm not sure, if this is a valid FUSE operation).

    You can try this with this python script: # python3 -c 'import os; os.write(os.open("HACKED", os.O_WRONLY | os.O_CREAT, dir_fd=os.open("::", os.O_PATH)), b"HACKED!");' - this should create a file named HACKED 1 level outside of the root directory of the VM.

    The fix for this should probably be more nuanced and resolve .. of / to just another reference to /, but for other directories, .. can be left to work normally (maybe?). I don't know what is the proper fix is - should .. be disallowed completely or just the path carefully resolved for root directory?

Note that this effects more that just the fuse LOOKUP operation - it also effects: unlink, symlink and anything else that deals with filenames.

mtjhrc avatar May 12 '25 16:05 mtjhrc