Patching Nixpkgs Pins

A while ago we noticed a small misconfiguration in a Nixpkgs file that was causing misleading warnings during system boot. A fix had already made it to Nixpkg’s master, but had not been backported to the release we were using.

As we had three related but distinct build configurations that all needed the fix, we were looking for a way to apply it to all of them uniformly. As they all made use of a shared pin of Nixpkgs already, a simple method proved to be applying a patch to the nixpkgs sources.

The core ingredient is a generic function that takes a source tree and a list of patches to apply to it, producing a patched source tree:

{ name, src, patches }:
    
(import <nixpkgs> {}).runCommand name
  { inherit src patches; }
  ''
    cp -r $src $out
    chmod -R +w $out
    for p in $patches; do
      echo "Applying patch $p";
      patch -d $out -p1 < "$p";
    done
  ''
patch-sources.nix

We need a bootstrap version of Nixpkgs (via the <nixpkgs> search path) purely to be able to use pkgs.runCommand.

Now we simply call this function with our Nixpkgs pin and import the result:

let
  nixpkgs = import ./patch-sources.nix rec {
    name = "nixos-21.11";
    src = builtins.fetchTarball {
      url = "https://github.com/nixos/nixpkgs/archive/${name}.tar.gz";
      sha256 = "04ffwp2gzq0hhz7siskw6qh9ys8ragp7285vi1zh8xjksxn1msc5";
    };
    patches = [ ./CVE-XYZ.patch ];
  };
in
import nixpkgs {};
Applying patch-sources.nix to pinned sources of Nixpkgs

We found this recipe tucked away in the NixOS wiki page for pinning Nixpkgs with pre-2.0 Nix, but think it deserves independent mention.