From 32ed9a733d60d808805fbaf341cf7ec2ddf43d38 Mon Sep 17 00:00:00 2001 From: Luna Nova Date: Fri, 2 Oct 2026 05:58:35 -0700 Subject: [PATCH] nixos/ccache: swap nix-ccache from perl script to writeCBin to avoid LPE --- nixos/modules/programs/ccache.nix | 37 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/nixos/modules/programs/ccache.nix b/nixos/modules/programs/ccache.nix index 4f6b5259afb9..0651e37a2a36 100644 --- a/nixos/modules/programs/ccache.nix +++ b/nixos/modules/programs/ccache.nix @@ -55,20 +55,31 @@ in inherit (cfg) owner group; setuid = false; setgid = true; - source = pkgs.writeScript "nix-ccache.pl" '' - #!${pkgs.perl}/bin/perl + source = lib.getExe ( + (pkgs.writeCBin "nix-ccache" '' + #include + #include + #include - %ENV=( CCACHE_DIR => '${cfg.cacheDir}' ); - sub untaint { - my $v = shift; - return '-C' if $v eq '-C' || $v eq '--clear'; - return '-V' if $v eq '-V' || $v eq '--version'; - return '-s' if $v eq '-s' || $v eq '--show-stats'; - return '-z' if $v eq '-z' || $v eq '--zero-stats'; - exec('${pkgs.ccache}/bin/ccache', '-h'); - } - exec('${pkgs.ccache}/bin/ccache', map { untaint $_ } @ARGV); - ''; + #define CCACHE "${lib.getExe pkgs.ccache}" + + int main(int argc, char *argv[]) { + regex_t allowed; + if (regcomp(&allowed, "^(-[CVsz]|--(clear|version|show-stats|zero-stats))$", REG_EXTENDED | REG_NOSUB)) + err(1, "regcomp"); + + // if any arg isn't on the allowlist, run `ccache` w/o args + for (int i = 1; i < argc; i++) + if (regexec(&allowed, argv[i], 0, nullptr, 0)) + argv[1] = nullptr; + + argv[0] = CCACHE; + execve(CCACHE, argv, (char *[]){ "CCACHE_DIR=${cfg.cacheDir}", nullptr }); + err(127, CCACHE); + } + '').overrideAttrs + { env.NIX_CFLAGS_COMPILE = "-std=c23"; } + ); }; })