Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

harden insecure permissions inside /dev/xen folder / research security impact of the Qubes /dev/xen folder permissions #9717

Open
adrelanos opened this issue Jan 16, 2025 · 5 comments
Labels
C: Xen P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. security This issue pertains to the security of Qubes OS.

Comments

@adrelanos
Copy link
Member

Qubes OS release

R4.2

Brief summary

Permissions inside /dev/xen folder might be insecure in context of preventing user to root local privilege escalation attacks.

Steps to reproduce

Exact steps are unknown. But since Qubes developer @DemiMarie states this, a ticket is warranted.

Issue

Quote @DemiMarie in #8823 (comment)

Right now, various devices under /dev/xen are accessible by any user in the qubes group. This is needed for unprivileged processes to use vchans, but likely allows escalation from the qubes group to root.

There are a couple of alternatives:

  1. Do nothing.
  2. Have every vchan-using program be set-user-id root. I’m not sure if this is a reasonable approach, especially because I don’t know if the Xen libraries are safe to use in setuid programs.
  3. Use a privileged daemon for all vchan and grant operations.
  4. Move the libvchan implementation into a kernel module. I very much like this approach, but it it is quite a bit more work.

Additional information

ls -la /dev/xen
total 0
drwxr-xr-x  2 root root      160 Jan 16 06:40 .
drwxr-xr-x 17 root root     3.9K Jan 16 06:42 ..
crw-rw----  1 root qubes 10, 122 Jan 16 06:40 evtchn
crw-rw----  1 root qubes 10, 121 Jan 16 06:40 gntalloc
crw-rw----  1 root qubes 10, 120 Jan 16 06:40 gntdev
crw-rw----  1 root qubes 10, 118 Jan 16 06:40 hypercall
crw-rw----  1 root qubes 10, 119 Jan 16 06:40 privcmd
crw-rw----  1 root qubes 10, 125 Jan 16 06:40 xenbus

Expected behavior

Secure permissions or any other secure implementation.

Actual behavior

Potentially insecure permissions.

@adrelanos adrelanos added P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. T: bug labels Jan 16, 2025
@andrewdavidwong andrewdavidwong added T: enhancement C: Xen security This issue pertains to the security of Qubes OS. and removed T: bug labels Jan 16, 2025
@ArrayBolt3
Copy link

ArrayBolt3 commented Jan 21, 2025

I did some research on this and discussed it with Demi and Marek in the Qubes OS Matrix room. I tried to condense down what I learned so that it's easier to figure out the next steps. Here's what I wrote down:

Qubes OS currently uses an in-qube security model that essentially assumes that gaining root within an individual qube is not a risk. This makes sense, since Qubes OS is designed to enforce isolation with AppVMs, not user accounts. However, as a form of defense-in-depth, it is worthwhile to prevent software from being able to get passwordless root access within a qube even though this isn't directly useful for isolating data from an attacker. The main reason for this is that most attacks that would allow breaking out of a VM into dom0 require that an attacker be able to get root in a VM first. Making this a hurdle could at least significantly increase the difficulty of an attack and potentially save users from becoming compromised when they otherwise would have been.

In order to allow Qubes OS's qrexec functionality to work, Qubes OS currently allows all devices under /dev/xen inside of a qube to be accessed by any user in the group qubes. This group includes the default user account, user. The reason this is necessary is because qrexec uses Xen's libxenvchan to allow data transfer between VMs. libxenvchan uses Xen grants in the background, which are a mechanism for sharing memory pages between VMs. Sharing memory to other VMs and gaining access to memory shared by other VMs requires the ability to use the /dev/xen devices (specifically gntdev, gntalloc, and privcmd), so they have to be accessible by everything that works with qrexec, including things that don't or shouldn't run as root. Each grant has a grant reference, which is basically an ID number used to refer to that grant.

The issue with Xen grants is that they only secure inasmuch as a block of memory shared with a particular VM will only be able to be accessed by the specified VM. Xen's grants are guest-agnostic, and so while they do prevent a malicious guest from gaining access to another guest's shared memory, they do not prevent processes from interfering with each other's grants. There is no concept of processes in Xen grants; the guest has to "do the right thing" with the memory it gives and receives, whatever "the right thing" is in each context.

This can potentially be used to corrupt data. A malicious process in a VM can very likely guess the grant ID used by a privileged component of the system (such as blkfront, Xen's virtual disk driver), and use it in unexpected ways. For instance, blkfront uses grants to communicate with dom0 for allowing disk contents to be sent back and forth. If a malicious process can guess a grant used by blkfront, it can attempt to tell other things in dom0 to use that same grant for other purposes (for instance, providing it to dom0 for use with qrexec). This should usually result in an error since two things will be trying to use the same area of memory at the same time, but it can potentially result in data corruption, which could potentially be used to gain kernel-level privileges within a qube.

Preventing this within the Linux kernel will probably require a driver that can provide functionality similar to libxenvchan but without requiring grant functionality to be exposed directly. This would allow qrexec to function without requiring the grant management devices to be directly accessible to almost everything in a qube. The kernel would still use grants in the background, but they would be abstracted away from the end user, and channel IDs would be managed separately from grant references.

(This is also in the Kicksecure dev documentation so it doesn't get lost: https://www.kicksecure.com/wiki/Dev/Qubes#Root_Privilege_Isolation_and_libxenvchan)

As for something actionable to be done, it seems the best solution is for someone to make an in-kernel, grant-based libxenvchan alternative in the kernel. Depending on what my priorities at work end up being, I may give this a shot.

@adrelanos
Copy link
Member Author

Quote @DemiMarie in #2695 (comment)

@adrelanos: What about the /dev/xen/* permissions issue? There are three ways I can think of to solve that:

  1. Add Xen support to AF_VSOCK or a similar kernel API.
  2. Make the various Qubes tools that use /dev/xen/* setuid root.
  3. Split the tools into privileged daemons and unprivileged command-line tools.

The GUI agent is going to be especially tricky. Since the X11 client libraries are not secure against malicious servers, this might require that the X server run as root for the GUI agent to work. This in turn runs into problems with the X server, which is badly maintained. The long-term solution is to transition to Wayland, but that has its own problems and will take a while.

@adrelanos
Copy link
Member Author

No strong opinions from my side.

  1. Dunno.
  2. SUID is to be avoided for reasons mentioned in Automate vm sudo authorization setup #2695. I would hope that one day there would be a system with zero SUIDs by default.
  3. Intuitively, sounds good.

But I would refer this to people more knowledgeable about Xen.

The GUI agent is going to be especially tricky. Since the X11 client libraries are not secure against malicious servers, this might require that the X server run as root for the GUI agent to work. This in turn runs into problems with the X server, which is badly maintained. The long-term solution is to transition to Wayland, but that has its own problems and will take a while.

I would hope that Wayland support (#3366) gets implemented eventually. Unless critically important, I would suggest to not spend any effort on X11 and rather redirect that effort towards Wayland.

This ticket could be implemented as if, assuming that the Qubes port to Wayland has already been completed to avoid one ticket blocking another.

@ArrayBolt3
Copy link

Based on prior discussions, I think option 1 is likely to be the most preferable. Having privileged daemons sounds good, but I think that runs into the X11 problems that Demi mentioned. It also means that any application implemented with libxenvchan has to be implemented in a similarly tricky manner, since the problem at its core is that the job libxenvchan does can't be done in a fully safe way in userland. Implementing a libxenvchan-like API in the kernel allows doing things like sharing files between VMs without a domU being able to make dom0 corrupt things.

@DemiMarie
Copy link

@ArrayBolt3 I think it would be best to use actual AF_VSOCK, as this is what KVM, VMware, systemd, and lots of userspace tools also support. Xen-specific features, like passing memory (as grant references), could be implemented using control messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: Xen P: default Priority: default. Default priority for new issues, to be replaced given sufficient information. security This issue pertains to the security of Qubes OS.
Projects
None yet
Development

No branches or pull requests

4 participants