-
-
Notifications
You must be signed in to change notification settings - Fork 15.1k
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
buildFHSEnv: binaries with capabilities cannot make use of them #217119
Comments
Perhaps related? #42117 |
This patch allows ANY application to request high priority queues, including SteamVR running in a bwrap container. See NixOS/nixpkgs#217119 Signed-off-by: Sefa Eyeoglu <[email protected]>
I have patched the relevant kernel code to allow ANY application to acquire high priority queues and added it to my NixOS configuration here: https://codeberg.org/Scrumplex/flake/commit/d6dc803d5cbb4a4dfd388489873bf446f0f56e34 Feel free to use this workaround, until we find a way to allow CAP_SYS_NICE in Steam's bwrap container. Edit: I have switched my NixOS config to use |
Taken from https://codeberg.org/Scrumplex/flake This works around NixOS/nixpkgs#217119 and flathub/com.valvesoftware.Steam#898 Signed-off-by: Sefa Eyeoglu <[email protected]>
Taken from https://codeberg.org/Scrumplex/flake This works around NixOS/nixpkgs#217119 and flathub/com.valvesoftware.Steam#898 Signed-off-by: Sefa Eyeoglu <[email protected]>
Is this still a problem in NixOS 23.11? |
Yes. This is a general issue with any binary that wants to use its capabilities but is sandboxed with bwrap |
https://jvns.ca/blog/2022/06/28/some-notes-on-bubblewrap/
it seems possible to add capabilities with bwrap, we could add a caps parameter to buildFHSUserEnv |
While that is true, these are ambient capabilities that'll apply to all processes inside the FHS environment. In the case of Steam, this would mean that all games would have I also remember that Steam does not like ambient capabilities at all. But that might have been bwrap itself. Not sure Edit: I am also pretty sure that |
I may have made some progress on this. I built
And then tried to start I removed the So I did a
Edit: I had to set
So, possibly no better than with bwrap.
|
Good news first: I've made some progress on this. To get access to certain (or all) caps, you can simply put the For easily testing whether caps work, we can use
If the cap is there, it'll print:
When I uncomment the SLR check in vrstartup.sh, I can get SteamVR to start in
Hooray! Bad news: This breaks steam. On startup, you get the generic "your system does not support userns" popup and this error message in the log:
Soooo how exactly are we supposed to add caps to the env if pressure-vessel errors out when it gets any access to caps? Pinging @smcv because you might know how this is intended to work. |
I celebrated to soon. In the vrcompositor.txt log it says:
So it appears while it has and recognises the cap inside bwrap, it doesn't actually have it from the kernel's perspective. Ugh. |
Yes. Capabilities are namespaced according to a user namespace: see bubblewrap can never give you capabilities in the initial user namespace, because each process can only ever have capabilities in the innermost user namespace that is applicable to it. The practical result is that nothing in NixOS' FHS environment will ever be able to have elevated capabilities in the initial user namespace. This is a kernel-imposed limitation, so there is nothing that user-space can do to solve it. SteamVR developers have attempted to avoid this kernel limitation by making AMDGPU use a more user-namespace-friendly check for whether to allow high-priority queues, but unfortunately there were concerns about this opening up new denial-of-service attacks, because of how the direct rendering manager interacts with memory management.
You can't. This error message is essentially bubblewrap saying: it looks as though I've been installed incorrectly, and I can't tell whether continuing would be a root security vulnerability, so I'm going to stop here. (Because bubblewrap has historically been installed setuid root, or occasionally setcap |
We do have access to the outside world though, so isn't there anything we could do there? We already use elevated privileges in the "root" namespace to give the vrcompositor binary caps; is it not possible to pass this privilege through to the userns somehow?
Thanks for the link! I can understand the worry of DOS but SteamVR being able to DOS my system is not part of my threat model, so I don't see why the user shouldn't be able to declare that to be the case via a limit or some other privileged mechanism. It's sad to need a kernel patch for an issue like this :/
Would it not be possible to have a build variant with a |
At the moment, you'll see that SteamVR uses an IPC call via It would in principle be possible to patch that so that it somehow(?) detects that it's in a nested user namespace (or detects that it's on NixOS, or something), and if yes, uses If someone successfully prototypes this by hacking the SteamVR scripts, we could ask the SteamVR developers about making that official. I do not have access to VR hardware or a NixOS system, so someone else will have to lead that.
No. The design of how This is why I have already had this discussion at exhaustive length with the SteamVR developers, and if there was a simple solution, we would be using it already. I still think that the long-term answer to this has to be some version of "don't use
Even if you patched out that check, processes inside the bwrap sandbox will never have Also, because of bubblewrap's history as being optionally-setuid and therefore being trusted by sysadmins as being safe-to-be-setuid, I would not be comfortable with providing that, even as an opt-in. I have too many responsibilities already, without opening myself up to being held responsible for new root privilege escalation CVEs. If you think I'm wrong about that, you will have to ask my bubblewrap co-maintainers to overrule me and take responsibility for any CVEs that result from it. Unfortunately my bubblewrap co-maintainers seem to have mostly disappeared (they also have too many responsibilities!) so if you go that route, you are likely to be waiting a while. |
From what I can tell, it's not actually namespaces that prevent capabilities from working. I am currently working on a bare-bones bubblewrap replacement for use in Nixpkgs FHSEnv wrappers and while reading bubblewrap's source code I have noticed that it mounts its sandboxed root with the I first thought it might be preferable to just strip out all the security-related code from bubblewrap, but after looking at the complexity, I have opted to write my own wrapper. You can find the current draft here: https://codeberg.org/Scrumplex/ancientwrap It can already setup a simple sandbox and mount things inside. I am currently working on implementing the options used by |
This defangs setuid binaries, but even if it didn't, they wouldn't work in a user namespace, because the kernel will only allow unprivileged users to create a user namespace with one uid (your own), and all other users including root get mapped to the overflow uid (which appears inside the container as
I'm surprised if it works without this. Last time I looked, this was a kernel requirement, without which the kernel would not allow unprivileged users to create a user namespace. (But perhaps newer kernels relax that restriction?) |
I would recommend reading |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/unable-to-activate-gamescope-capsysnice-option/37843/9 |
Flatpak steam runs into the same issue. It might be possible to have a service (on dbus?) outside the FHS env that can be asked to increase the priority of the VR compositor. SteamVR would have to integrate with it, or we could LD_PRELOAD something that hijacks the renice call and goes via the external service. I was hoping flatpak had already implemented a solution and we could use it instead of having something custom, but they haven't, and SteamVR doesn't integrate with anything that would workaround this. |
I meant requesting renicing in a more restricted way, like other requests using portals that are able to be safer than arbitrary host code execution. I don't really like the way you filled in [] with something far from what I intended as if that's the only thing I could have meant :c |
The issue here is not niceness per-se, but the capability to re-/nice. For the mechanism in question (initialization of a high priority drm context) the kernel requires the calling process to have the CAP_SYS_NICE capability.[1] This is just something that isn't possible in user namespaces using file capabilities. A workaround would be to add it as an ambient capability to every process in the fhsenv, but that might be too permissive and requires bwrap to be a setuid binary. A proper fix would require changes to the kernel, and several were proposed before to handle this use case without capabilities[2], though none have made it to the mainline kernel. |
Yes, SteamVR does not implement any mechanism for requesting renicing, however desirable that might be. The only mechanism it has is a way to ask to execute arbitrary code "outside", because that is the only way it can possibly get one of the process parameters it wants. My understanding is that the
The first of those two can be achieved by mechanisms like the Realtime portal, and if that was sufficient, there would be no problem. But The |
There were several proposals from an Intel developer, as summarized here: https://lore.kernel.org/dri-devel/[email protected]/ |
From the reply, those didn't seem likely to be accepted either, without a DRI expert doing a lot of research first. |
It is slightly horrifying that the kernel side of this insists on this. |
Please note that we are in the same situation as Flatpak here for which there are quite a few more people who'd like to use SteamVR. If there is a solution that works for Flatpak, we can likely make it work for our purposes too, so please focus on Flatpak first.
We don't really care about sandboxing here. We only use bubblewrap to emulate the FHS "API" such that games are able to use our shared libraries. If we could do that without a NS, we would.
From what I gathered, that's because you could DOS the system memory using a high-priority queue. Arguably, CAP_SYS_NICE isn't even enough of a permission to allow this. |
Just chiming in here, we get at least one nix user a day who drops in and gets the flyswatter of this issue. I invite you to join LVRA, we've got a large segment of users I believe you are unable to see from your vantage, and my hope is you can see what we're building out here. |
I wonder: does this issue still happen when using |
this has been explored before. See #217119 (comment) |
Landed here from the wiki. The kernel patch that's at the end of the article mentions amdgpu, but is there any equivalent for nvidia? I tried this anyway and it didn't do anything. |
While I don't know of a patch, I discussed this previously and I think the following code needs to be changed to always return |
This property appears to be intended by the kernel. There is nothing we can do about that, so I'm going to close this as WONTFIX. If someone comes up with a method to emulate an FHS environment without utilising namespaces, we can re-open this. |
I don't quite understand why this issue should be closed. This is an issue about the way we package some applications in Nixpkgs and while the root cause is kernel behaviour it is still a bug in NixOS. No other distribution is affected by this issue, unless you treat Flatpak as its own distribution, of course. There is a possibility of this being fixed in the future, so I think this issue should be kept open. |
It's because there is nothing actionable for us to do. We're not even blocked on something, there is nothing on the horizon that could help alleviate this issue. Tracking issues that we cannot do anything about is not a good use of our time. Leaving issues open despite them not being actionable is also confusing. If this were to be "fixed" on the kernel side in the future, it'd be introduced to our kernels as part of the regular flow of updates anyways, so there would still be nothing actionable for us even in that case. As mentioned, if someone does come up with something that is actionable for us, we can always re-open and then focus on getting that path to work. |
Do we have to use user namespaces or is there any other way to emulate FHS? Could something like building the directory structure and then setting up the PATHs work? I'm not too familiar with how Steam works and what all is hard-coded |
The problem is that the binaries hard-code their ld.so and we can't modify the binaries. You must have a global ld.so and the only way to do that without having an actually global ld.so is a namespace. |
I feel like this should be kept open with the https://github.com/NixOS/nixpkgs/labels/2.status%3A%20wait-for-upstream or https://github.com/NixOS/nixpkgs/labels/2.status%3A%20wontfix label |
As I said, there is nothing to wait on here as there is nothing on the horizon which could fix this. Wontfix is for closed issues and I think its from before GH had that feature natively. |
Added the needs upstream fix label anyway. I feel like this issue should remain open, even if nothing can be done on our side. Someone might stumble across it and not file a duplicate issue, or might even have some ideas to share on how to solve this situation. |
It's not a good fix but a module option (under hardware.steam?) to patch out the kernel checks for this might be acceptable, specifically aimed at the steam VR usecase rather than capabilities in FHS env in general. If I understand correctly that would be opting into any process being able to hang your graphics (local DoS), and wouldn't allow for privilege escalation or sandbox escapes. |
@LunNova See option and implementation in my config aswell as #321663 (or my port). |
If you end up here because you maybe want to launch Steam from Lutris or Sunshine, try changing the steam command to something like:
|
Describe the bug
SteamVR has the capability to use asynchronous reprojection to increase the perceived frame rate in VR applications.
To achieve this, it needs to request a VkDevice with a high priority queue.
AMDGPU requires applications to have the
CAP_SYS_NICE
capability [1], which is usually requested when starting SteamVR for the first time.Making sure that
~/.steam/steam/steamapps/common/SteamVR/bin/linux64/vrcompositor-launcher
has the necessary capability:But SteamVR still fails to acquire a high-priority queue and disables asynchronous reprojection.
Steps To Reproduce
Steps to reproduce the behavior:
vrcompositor-launcher
hasCAP_SYS_NICE
:setcap getcap ~/.steam/steam/steamapps/common/SteamVR/bin/linux64/vrcompositor-launcher ~/.steam/steam/steamapps/common/SteamVR/bin/linux64/vrcompositor-launcher
Expected behavior
SteamVR is able to acquire a high priority queue and continues to use async reprojection.
Logs
vrcompositor.log:
Additional context
My hardware supports this feature, as I have been using SteamVR with async reprojection on Arch Linux before.
Notify maintainers
@mkg20001 @jagajaga
Metadata
Please run
nix-shell -p nix-info --run "nix-info -m"
and paste the result.The text was updated successfully, but these errors were encountered: