`sudo` does not work from within vscode-fhs

I am just trying vscode-fhs, however it seems I cannot run nixos-rebuild.

Can someone help?
I would really like to run this from vscode and the fhs version is just so much more comfortable.

$ sudo nixos-rebuild switch                                                                     
sudo: /nix/store/yx5zifiwsc7zbd54zs7l8i4a6nrrg6wf-wrapper.c:195: main: Assertion `!(st.st_mode & S_ISUID) || (st.st_uid == geteuid())' failed.
[1]    315 IOT instruction (core dumped)  sudo nixos-rebuild switch

EDIT:
it seems like I cannot run any sudo command…

$ sudo ls    
sudo: /nix/store/yx5zifiwsc7zbd54zs7l8i4a6nrrg6wf-wrapper.c:195: main: Assertion `!(st.st_mode & S_ISUID) || (st.st_uid == geteuid())' failed.
[1]    342 IOT instruction (core dumped)  sudo ls

This is because the nix store doesn’t allow for setuid. This is handled by wrappers in /run/wrappers on NixOS:

$ ls -l /run/wrappers/bin/sudo*
.r-s--x--x 18k root 24 Jul 06:51 /run/wrappers/bin/sudo
.rw-r--r--  63 root 24 Jul 06:51 /run/wrappers/bin/sudo.real
.r-s--x--x 18k root 24 Jul 06:51 /run/wrappers/bin/sudoedit
.rw-r--r--  67 root 24 Jul 06:51 /run/wrappers/bin/sudoedit.real

and your PATH just has it listed first:

$ echo $PATH
/run/wrappers/bin:/home/jon//.nix-profile/bin:/etc/profiles/per-user/jon/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:/home/jon//.cargo/bin:/home/jon//.config/nixpkgs/bin

Unfortunately, the /run/wrappers isn’t currently mounted inside of the fhs sandbox, so it’s not available.

1 Like

thank you very much for explaining.

is it possible to fix buildFHSUserEnv in order to fix this? How would you do it?

looks like I lied a bit, /run/wrappers is still available. However, I would assume some of the unshared kernel namespaces are affecting sudo from working correctly.

If someone wants to figure out, then… god’s speed. But I think the need to run commands with sudo are pretty low, should just be able to run the commands in a normal terminal until someone figures it out with bubblewrap (if it’s even possible).

1 Like

It is impossible to use SUID applications from within user namespaces for good reason. Otherwise an unprivileged user could simply bind a crafted /etc/sudoers and become root.

3 Likes

hi @hmenke it sounds like you understand what is going on. Maybe you could share some

As a user I am authenticating with sudo to use admin priveleges. Mind with me, of course I don’t know all the details of buildFHSUserEnv, but intuitively this could be done within it as well, couldn’t it? I am my user and can authenticate with my user id I thought.


Considering vscode-fhs, what are the concrete option available to run sudo in the terminal?

As a user I am authenticating with sudo to use admin priveleges. Mind with me, of course I don’t know all the details of buildFHSUserEnv, but intuitively this could be done within it as well, couldn’t it? I am my user and can authenticate with my user id I thought.

The intention of buildFHSUserEnv is to provide some isolation from the host machine, in that regard, this is working as intended.

Considering vscode-fhs , what are the concrete option available to run sudo in the terminal?

If I come off as condescending, I don’t mean to. But you can open any other terminal or terminal emulator which isn’t sandboxed, and use it.

1 Like

Consider the file /tmp/evil_sudoers with the content

ALL ALL=(ALL) NOPASSWD:ALL

Now I can create a user namespace with bubblewrap Ă  la

$ bwrap --bind /nix /nix --bind /run /run --bind /tmp/evil_sudoers /etc/sudoers bash
bash-4.4$ cat /etc/sudoers 
ALL ALL=(ALL) NOPASSWD:ALL

and if sudo was working inside the user namespace I would have just successfully elevated my privileges by allowing anyone to invoke sudo without password.

3 Likes

as I stumble upon this issue on daily basis a little followup question (still using vscode-fhs because of its better support for installing extensions via vscode itself)

@hmenke

  • would it be possible to build a safe restricted version of bubblewrap which makes sure that you cannot circumvent user rights, e.g. by hardcoding that /etc/sudoers stays the same?
  • could we then enable sudo for these custom fhs?

thank you a lot for your help and input

It might be possible if you are willing to run bubblewrap as root, but that is probably not an acceptable solution and is also very susceptible to catastrophic security vulnerabilities.

A more useful solution would be to have a client-server model where you communicate with sudo via a pipe. However, if the pipe is unauthenticated, everyone else can just snoop the root password from the pipe, so there is also a tradeoff to be made there.

EDIT: Another possible solution might be a buildFHSEnv based on PRoot. However, this will require ptrace and comes at a quite substantial performance cost. All the Linux namespace wrappers (bubblewrap, NixOS user chroot, firejail, etc.) seem to enforce PR_SET_NO_NEW_PRIVS which means suid binaries cannot be executed. Rightfully so, in my opinion, because suid binaries allow the jailed application to break out and elevate its privileges.

EDIT2: Turns out that PRoot also sets PR_SET_NO_NEW_PRIVS, so the only remaining possibility I can think of is an actual chroot with bind mounts. This will require superuser privileges to set up, but before starting the nested application privileges can be dropped again.

Has anyone been able to solve this? I’m having the same issue with vscode-fhs and I don’t know how to fix it.

Thanks!

The answer is pretty clear:

All the Linux namespace wrappers (bubblewrap, NixOS user chroot, firejail, etc.) seem to enforce PR_SET_NO_NEW_PRIVS 5 which means suid binaries cannot be executed. Rightfully so, in my opinion, because suid binaries allow the jailed application to break out and elevate its privileges.

I.e., for security reasons, this is not possible. If you want to run a command as root, you have to do it in a terminal not launched by vscode.

Alternatively, you could use the vscode (or vscodium) versions that are not inside an fhs env. Those cannot use extensions that aren’t specifically tweaked to run on NixOS, though - such extensions do live inside nixpkgs, so it’s viable (and I’d argue preferable), just less convenient.

It was not clear to me at all :sweat_smile: thanks for the clear explanation :+1:

I think I’ll eventually move to the programs.vscode, not sure how much I trust the vscode sync mechanism anyways

I had to fix this for 1password agents, but it by extension allows you to use setuid binaries as well!

I changed the default shell to use systemd-run to spawn it outside the FHS sandbox and from there all commands work as expected! (there may be some side effects but other than the command name being incorrect in the UI I haven’t noticed anything)

2 Likes

That’s a fun solution! I guess the systemd socket remains available in the fhs, and systemd-run is a nice way to invoke stuff through it without being bound to the current process’ settings. Kinda makes me wonder how easy it is to escape more security-critical sandboxes this way.

You may be able to change the process name with the @ prefix:

If the executable path is prefixed with “@”, the second specified token will be passed as argv[0] to the executed process (instead of the actual filename), followed by the further arguments specified.

I’m not 100% sure the ExecStart syntax fully carries over to systemd-run though.

1 Like

run0 can be used instead of sudo in vscode-fhs

1 Like