|Summary:||sysutils/grub2-bhyve: "(host)" filesystem is a potential security issue|
|Product:||Ports & Packages||Reporter:||noah.bergbauer|
|Component:||Individual Port(s)||Assignee:||freebsd-ports-bugs (Nobody) <ports-bugs>|
|Severity:||Affects Only Me||CC:||emaste, grehan, jhb|
Description noah.bergbauer 2018-09-19 14:55:41 UTC
Grub-bhyve has access to the host filesystem through the '(host)' pseudofs. Considering that the typical Linux guest would have its grub configuration on its boot partition (as the handbook suggests: https://www.freebsd.org/doc/handbook/virtualization-host-bhyve.html) this means that having root permissions on the guest allows you to access the host filesystem on the next VM boot, for example: * Add "source (host)/root/secret.txt" to the head of grub.cfg * Add "myvalue=$password" to the kernel command line * Shut down VM * On the host: "echo password=verysecret12345 > /root/secret.txt" * Launch VM $ cat /proc/cmdline console=ttyS0 BOOT_IMAGE=/boot/vmlinuz-4.4.0-75-generic root=UUID=e757cf85-936a-4fe8-b099-54046961756d ro myvalue=verysecret12345 $ As you can see this might be a critical information leak in certain circumstances, especially because you have to (?) run grub-bhyve as root on the host system. Perhaps an option could be added to chroot the bootloader once it is done loading libraries and opening image/disk files? Module loading is disabled so the filesystem appears to be the only remaining attack surface.
Comment 1 John Baldwin 2019-12-10 19:13:52 UTC
Hmm, bhyveload doesn't provide a host filesystem by default unless it is enabled via a command line argument and the argument gives a subdirectory that all requests are made within. (There's no prevision for escaping the subdirectory via .. symlinks though IIRC.) I haven't looked at grub2-bhyve, but it seems like it should similarly only enable (host) if specifically configured by the user and not by default.
Comment 2 Conrad Meyer 2020-02-02 23:27:38 UTC
The change proposed in https://github.com/grehan-freebsd/grub2-bhyve/pull/12 limits filesystem access to that available as user 'nobody' rather than 'root'. I like John's proposal as well.
Comment 3 Conrad Meyer 2020-02-15 21:41:04 UTC
bhyveload(1) uses the '-h hostdir' flag for this. This is similar to '-r host -d hostdir' in grub-bhyve syntax; however, '-r host' is the default in grub-bhyve. '-h' is available in grub-bhyve, but I would avoid using it for anything other than '--help'. We could treat explicit '-r host' similar to explicit '-h hostdir' in grub-bhyve. That is, do not allow host filesystem access _at all_ unless '-r host' was specifically provided as a parameter. This would retain compatibility with vm-bhyve's use of '-r host', while denying host filesystem access by default. Thoughts? I'll propose a patch via github eventually but I view this as orthogonal to the privdrop proposal above, and will wait until that is resolved.
Comment 4 John Baldwin 2020-03-19 22:57:56 UTC
I think requiring -r host explicitly makes sense
Comment 5 Conrad Meyer 2020-03-30 23:45:25 UTC
The github PR has been merged, so (host) is now read-only and access limited to the unprivileged 'nobody' user. That (?)might be sufficient to resolve this bug as-reported, since most secrets will not be readable by user 'nobody'. That said, the guest should not have arbitrary 'nobody'-level read access to the host filesystem anyway, so it's still a privilege escalation that needs fixed. Adding chroot()+chdir() (both are essential!) in the non-'-r host' case is pretty trivial, if someone wants to tackle that. I can help provide pointers but I think I'm done with grub-bhyve work myself for the time being.
Comment 6 Peter Grehan 2020-03-31 00:27:03 UTC
Send me your pointers: I'll try and get that done.
Comment 7 Conrad Meyer 2020-07-30 15:47:36 UTC
(In reply to Peter Grehan from comment #6) Apologies, somehow I missed this folow-up. I think with our pre-opened fd cache, we can just chdir("/var/empty") and chroot(".") in grub_emu_bhyve_post_init() (or cap_enter() on Capsicum systems). We're already doing (host) access via fd-relative opens, I think. I'm not sure why I didn't add that additional step back in March! It shouldn't impact much desired functionality and would complete the sandbox. Worth mentioning there's a few more Grub cfg-running related vulnerabilities described recently here: https://eclypsium.com/2020/07/29/theres-a-hole-in-the-boot/ . The top-level lexing one likely impacts us.