Security fix: Nix fixed-output derivation sandbox bypass

tl;dr: CVE-2024-27297 (or here if the CVE index doesn’t show it yet) was published earlier today, please update your Nix installation.

@jade and @puckipedia reported a security issue in Nix allowing a malicious fixed-ouput derivation (FOD) to change its content after it has been registered by Nix, potentially contaminating non-fixed-output derivations down the line. It has been patched in the following Nix versions:

The issue occurs because the FOD sandbox allows derivations to share abstract Unix sockets with each other and with the host, and these sockets can be used to pass file descriptors around. It is thus possible for a derivation to send a file descriptor to its output to another program (either directly running on the machine, or in another fixed-output derivation). That file descriptor will stay open after the build is done, and that other program can then use it to change the path in the store.

We have applied a patch to fix the time-of-check/time-of-use bug by copying the paths before verifying them, and intend to sandbox fixed-output derivations even better in the future.

More details in the GitHub security advisory.

How to update

  • If you’re following nixos-unstable-small, the fix is already in the latest update of the channel;
  • If you’re following nixos-unstable, nixos-23.11-small or nixos-23.11, the corresponding release- branches already have the working versions so they should reach the channels shortly;
  • If you don’t, or if you can’t afford to wait, you can directly fetch the source from the patches above.
27 Likes

great work @jade and @puckipedia!

3 Likes

Is it possible to list the relevant nixpkgs PR(s), so that people can track when they land on the respective channels?


EDIT: I’ve found these two

8 Likes

Thanks for your work in identifying and fixing this…

Pardon my noob question, but it seems I have many versions of Nix on my system. I do run GC fairly often - sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 14d; nix-collect-garbage --delete-older-than 14d, but I still have some pretty ancient versions like 2.8.1:

nix --version
nix (Nix) 2.18.1

ls -l $(which nix)
lrwxrwxrwx 1 root root 62 Dec 31  1969 /run/current-system/sw/bin/nix -> /nix/store/62fm7r6175k2bgvhc19hn9bdhw90wa3n-nix-2.18.1/bin/nix

ls /nix/store/ | grep \\.drv | grep '\-nix-2\.'
62w80ysadiwccavibcmq9l7xqpf95n7m-nix-2.18.1.drv
6wfxr4zgqmnhvn9kxwfrvl41ml2zd7hk-nix-2.18.1.drv
cygz1xd196yjqnf5nl168c84hgkgavq0-nix-2.11.0.drv
h70q1h9rifyhfsw26layz543zyndxalp-nix-2.11.1.drv
ij8kkxmfqxxpn0r770cdgdrs1y7wcwia-nix-2.15.3.drv
kpk2f406wqpqm13s9yfwaj29h46r3aws-nix-2.15.3.drv
vpf2y4jz1vm2rgc765zi5lflgcx864pm-nix-2.8.1.drv
zg8pvk4nxlq8xzpyl02glgrfc20h9i0a-nix-2.12.0.drv
zxbs4za5gfygqxmwx29q5n777j9nq42q-nix-2.18.1.drv

These old versions are now getting rightly flagged as insecure when I try to sudo nixos-rebuild switch --upgrade, I know from the error I can do nixpkgs.config.permittedInsecurePackages on them… but I’m curious what the proper way to manage and remediate these would be?

1 Like

rnix-lsp is the package that was requiring nix-2.15.3, per this thread…

Unfortunately, I’m still a bit lost as to how that was determined… maybe by greping nixpkgs.

I found out which package way causing the issue by first adding the nix version to config.permittedInsecurePackages, as prompted by the error message. Then, when running sudo nixos-rebuild switch --verbose, it will start building the old nix from source (because it isn’t cached anymore), and the --verbose flag will cause it to show what packages still need to be built. (rnix-lsp being one of them)

2 Likes

You can find this out with nix-store --query --referrers /nix/store/...nix-2.15.3 or for your current system you can use nix path-info and nix why-depends:

nix path-info -r /run/current-system | grep nix-2.15.3
nix why-depends -a /run/current-system /nix/store/...nix-2.15.3

Maybe you need to look in your home-manager generation instead of current system.

1 Like