From af665d822a166ae62547c1c310207f11acaded17 Mon Sep 17 00:00:00 2001 From: volth Date: Wed, 18 Sep 2019 22:34:41 +0000 Subject: [PATCH 1/2] add config.environment.ld-linux Add option to install symlink to ld-linux(8) system-wide to allow running unmodified ELF binaries. It might be useful to run games or executables distributed inside jar files as discussed https://discourse.nixos.org/t/runtime-alternative-to-patchelf-set-interpreter/3539 https://discourse.nixos.org/t/running-binaries-without-fhs-and-patchelf/1828 It is the third concession to FHS after `/bin/sh` and `/usr/bin/env` but it is disabled by default unlike those two --- .../system/activation/activation-script.nix | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index ddfd1af4a319..9141c8222b73 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -162,6 +162,16 @@ in /usr/bin/env. ''; }; + + environment.ld-linux = mkOption { + default = false; + type = types.bool; + visible = false; + description = '' + Install symlink to ld-linux(8) system-wide to allow running unmodified ELF binaries. + It might be useful to run games or executables distributed inside jar files. + ''; + }; }; @@ -198,6 +208,27 @@ in rmdir --ignore-fail-on-non-empty /usr/bin /usr ''; + system.activationScripts.ld-linux = + concatStrings ( + mapAttrsToList + (target: source: + if config.environment.ld-linux then '' + mkdir -m 0755 -p $(dirname ${target}) + ln -sfn ${escapeShellArg source} ${target}.tmp + mv -f ${target}.tmp ${target} # atomically replace + '' else '' + rm -f ${target} + rmdir --ignore-fail-on-non-empty $(dirname ${target}) + '') + { + "i686-linux" ."/lib/ld-linux.so.2" = "${pkgs.glibc.out}/lib/ld-linux.so.2"; + "x86_64-linux" ."/lib/ld-linux.so.2" = "${pkgs.pkgsi686Linux.glibc.out}/lib/ld-linux.so.2"; + "x86_64-linux" ."/lib64/ld-linux-x86-64.so.2" = "${pkgs.glibc.out}/lib64/ld-linux-x86-64.so.2"; + "aarch64-linux"."/lib/ld-linux-aarch64.so.1" = "${pkgs.glibc.out}/lib/ld-linux-aarch64.so.1"; + "armv7l-linux" ."/lib/ld-linux-armhf.so.3" = "${pkgs.glibc.out}/lib/ld-linux-armhf.so.3"; + }.${pkgs.stdenv.system} or {} + ); + system.activationScripts.specialfs = '' specialMount() { From 45db499d2de2235388212a911b8344b58ddfda36 Mon Sep 17 00:00:00 2001 From: volth Date: Thu, 19 Sep 2019 00:32:35 +0000 Subject: [PATCH 2/2] rmdir: avoid failing when directory did not exist I bet nobody has `environment.usrbinenv = null`, it would fail on the second activation trying to `rmdir` inexisting `/usr/bin` --- nixos/modules/system/activation/activation-script.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 9141c8222b73..495d77dfd497 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -205,7 +205,7 @@ in '' else '' rm -f /usr/bin/env - rmdir --ignore-fail-on-non-empty /usr/bin /usr + rmdir -p /usr/bin || true ''; system.activationScripts.ld-linux = @@ -218,7 +218,7 @@ in mv -f ${target}.tmp ${target} # atomically replace '' else '' rm -f ${target} - rmdir --ignore-fail-on-non-empty $(dirname ${target}) + rmdir $(dirname ${target}) || true '') { "i686-linux" ."/lib/ld-linux.so.2" = "${pkgs.glibc.out}/lib/ld-linux.so.2";