Today I gave this a go on my laptop. I’m using a flake-based NixOS configuration.
First I looked which processes are using openssl:
$ sudo lsof $(nix build --inputs-from . nixpkgs#openssl.out --print-out-paths)/lib/libssl.so
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nix-daemo 1258 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
NetworkMa 1439 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
redis-ser 1584 redis mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
wpa_suppl 1636 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
.flamesho 2082 bob.vanderlinden mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
It seems that at least these processes are using libssl of openssl 3.0.5 (the version of openssl in nixpkgs defined in the flake lock file).
Next I added the following to my NixOS configuration:
system.replaceRuntimeDependencies = [{
original = pkgs.openssl;
replacement = pkgs.openssl.overrideAttrs (oldAttrs: {
version = "3.0.X";
});
}];
This doesn’t really patch openssl, but just changes the nix-store path from openssl-3.0.5
to openssl-3.0.X
, just so I can see that processes are indeed using 3.0.X and not 3.0.5 anymore.
I attempt to apply the configuration for the next boot:
$ nixos-rebuild --use-remote-sudo --flake . boot
error: 'builtins.storePath' is not allowed in pure evaluation mode
at /nix/store/9m8drnpifyl5qsx93g6ll2xw6wkps03z-source/pkgs/build-support/replace-dependency.nix:49:18:
48|
49| oldStorepath = builtins.storePath (discard (toString oldDependency));
| ^
50|
(use '--show-trace' to show detailed location information)
Ah, so apparently using flakes implies a pure evaluation and system.replaceRuntimeDependencies
is impure. I’ll apply the configuration using --impure
(which succeeds) and reboot the system:
$ nixos-rebuild --use-remote-sudo --flake . boot --impure
$ reboot
After rebooting there are still processes using the original openssl version:
$ sudo lsof $(nix build --inputs-from . nixpkgs#openssl.out --print-out-paths)/lib/libssl.so
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nix-daemo 1314 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
NetworkMa 1436 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
redis-ser 1581 redis mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
wpa_suppl 1653 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
.flamesho 2007 bob.vanderlinden mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
Next, I tried setting LD_LIBRARY_PATH
. I have tried environment.variables.LD_LIBRARY_PATH
, but that doesn’t apply to systemd services. So, next I tried systemd.globalEnvironment.LD_LIBARY_PATH
as follows:
systemd.globalEnvironment.LD_LIBRARY_PATH =
let
openssl-patched = pkgs.openssl.overrideAttrs
(oldAttrs: {
version = "3.0.X";
});
in
"${openssl-patched.out}/lib";
After rebooting most processes are indeed using 3.0.X and not 3.0.5 anymore. Only wpa_supplicant
showed up as using openssl-3.0.5
:
$ sudo lsof $(nix build --inputs-from . nixpkgs#openssl.out --print-out-paths)/lib/libssl.so
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
wpa_suppl 1650 root mem REG 254,1 808120 7345799 /nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5/lib/libssl.so.3
Maybe wpa_supplicant
overwrites LD_LIBRARY_PATH
, or has openssl hardcoded some other way. Not sure. I haven’t dug into this further, as I’m more interested in making system.replaceRuntimeDependencies
work.
I’m interested why system.replaceRuntimeDependencies
doesn’t work for me. Flakes? Impure? Something else?
Also, is using lsof valid for checking whether processes are still using openssl 3.0.5?
EDIT: Also interesting is using why-depends to determine which parts of the system are depending on the unpatched openssl version:
$ nix why-depends --all --inputs-from . .#nixosConfigurations.$HOST.config.system.build.toplevel nixpkgs#openssl.out
/nix/store/hjsna4y11n30l8pc6ql2jqfcqd8k9g23-nixos-system-NVC3919-22.11.20221025.f994293
├───/nix/store/77c9qlw0mmzbhl5f72sxqrxzrkyynds0-systemd-251.5
│ ├───/nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5
│ ├───/nix/store/1mdiz3knga8234bigm4hgz35rgxkypa4-curl-7.85.0
│ │ ├───/nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5
│ │ └───/nix/store/59a9bq5kjfjm2i8hhdnalc8g7cv9cxq2-libssh2-1.10.0
│ │ └───/nix/store/9cj4b9c912dmisk35npiakjk7mjqr3wn-openssl-3.0.5
│ ├───/nix/store/ab74lf55czfd6pl8af83dgnrw714pdv8-libfido2-1.12.0
...
Not sure whether this output should change when using system.replaceRuntimeDependencies
?