Skip to content

Commit 8a9cac1

Browse files
author
Cassandra Comar
committed
feat: execute binary specified by $0
thread argv0 through the arx call stack so we can select the binary in the target's bin path based on it. this also fixes an issue with fakedir where running `Dir.pwd` within ruby would cause a segfault due to a null ptr dereference.
1 parent 9116f7c commit 8a9cac1

File tree

4 files changed

+87
-22
lines changed

4 files changed

+87
-22
lines changed

arx-multi-bin.patch

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
diff --git a/model-scripts/tmpx.sh b/model-scripts/tmpx.sh
2+
index 9c2ec6f..aa6fea9 100755
3+
--- a/model-scripts/tmpx.sh
4+
+++ b/model-scripts/tmpx.sh
5+
@@ -4,6 +4,7 @@ unset rm_ dir
6+
tmp=true ; run=true
7+
tmpdir= ; rm0=true ; rm1=true ; shared=false ; hash="" # To be set by tool.
8+
token=`date -u +%FT%TZ | tr -d :-`-`hexdump -n4 -e '"%08x"' </dev/urandom`
9+
+prog_name="$0"
10+
opts() {
11+
cmd="$1" ; shift
12+
n=$#
13+
@@ -39,9 +40,9 @@ opts() {
14+
if $shared
15+
then
16+
rm_=false
17+
- dir="$tmpdir"/tmpx-"$hash"
18+
+ dir="$HOME"/.cache/tmpx-"$hash"
19+
else
20+
- dir="$tmpdir"/tmpx-"$token"
21+
+ dir="$HOME"/.cache/tmpx-"$token"
22+
fi
23+
: ${rm_:=true}
24+
if $rm_
25+
@@ -53,6 +54,7 @@ opts() {
26+
trap 'exit 2' HUP INT QUIT BUS SEGV PIPE TERM
27+
fi
28+
mkdir -p "$dir"
29+
+ export TMPX_RESTORE_PWD=$(pwd)
30+
cd "$dir"
31+
fi
32+
# Call the command with the reassembled ARGV, options removed.
33+
@@ -72,7 +74,10 @@ go () {
34+
fi
35+
if $run
36+
then
37+
- ( . ../env && exec ../run "$@" )
38+
+ (
39+
+ . ../env
40+
+ exec -a "${prog_name}" sh -c ". ../run" "${prog_name}" "$@"
41+
+ )
42+
fi
43+
}
44+
unpack_env () { : # NOOP

default.nix

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ with nixpkgs;
77

88
let
99
arx' = haskellPackages.arx.overrideAttrs (o: {
10-
patchPhase = (o.patchPhase or "") + ''
11-
substituteInPlace model-scripts/tmpx.sh \
12-
--replace /tmp/ \$HOME/.cache/
13-
'';
10+
patches = (o.patches or []) ++ [./arx-multi-bin.patch];
1411
});
1512
in rec {
1613
toStorePath = target:
@@ -27,7 +24,7 @@ in rec {
2724
stdenv.mkDerivation {
2825
name = "arx";
2926
buildCommand = ''
30-
${arx'}/bin/arx tmpx --shared -rm! ${archive} -o $out // ${startup}
27+
${arx'}/bin/arx tmpx --shared -rm! ${archive} -o $out -e ${startup}
3128
chmod +x $out
3229
'';
3330
};
@@ -94,15 +91,17 @@ in rec {
9491
# Avoid re-adding a store path into the store
9592
path = toStorePath target;
9693
script-linux = ''
97-
.${nix-user-chroot'}/bin/nix-user-chroot -n ./nix ${nixUserChrootFlags} -- ${path}${run} "$@"
94+
exec .${nix-user-chroot'}/bin/nix-user-chroot -n ./nix ${nixUserChrootFlags} -- ".$(basename "$0")/$(dirname ${path}${run})" "$@"
9895
'';
9996
script-macos = ''
10097
# use absolute paths so the environment variables don't get reinterpreted after a cd
101-
cur_dir=$(pwd)
102-
export DYLD_INSERT_LIBRARIES="''${cur_dir}/lib/libfakedir.dylib"
98+
__TMPX_DAT_PATH=$(pwd)
99+
cd "''${TMPX_RESTORE_PWD}"
100+
export DYLD_INSERT_LIBRARIES="''${__TMPX_DAT_PATH}/lib/libfakedir.dylib"
103101
export FAKEDIR_PATTERN=/nix
104-
export FAKEDIR_TARGET="''${cur_dir}/nix"
105-
exec .${path}${run} "$@"
102+
export FAKEDIR_TARGET="''${__TMPX_DAT_PATH}/nix"
103+
104+
exec "''${__TMPX_DAT_PATH}$(basename "$0")/$(dirname ${path}${run})/$(basename "$0")" "$@"
106105
'';
107106
script = if stdenv.isDarwin then script-macos else script-linux;
108107
in
@@ -116,7 +115,7 @@ in rec {
116115
let
117116
script = makeStartup { inherit target nixUserChrootFlags nix-user-chroot' run initScript; };
118117
in makebootstrap {
119-
startup = ".${script} '\"$@\"'";
118+
startup = script;
120119
targets = [ "${script}" ] ++ extraTargets;
121120
};
122121

fakedir-null-buffer.patch

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
diff --git a/trivial_replacements.c b/trivial_replacements.c
2+
index 8de580f..c33ef25 100644
3+
--- a/trivial_replacements.c
4+
+++ b/trivial_replacements.c
5+
@@ -1,4 +1,5 @@
6+
#include "common.h"
7+
+#include <string.h>
8+
9+
/**
10+
* @file trivial_replacements.c
11+
@@ -309,8 +310,11 @@ ENDSUBST
12+
13+
SUBST(char const *, getcwd, (char *buf, size_t size))
14+
pthread_mutex_unlock(&_lock);
15+
- getcwd(buf, size);
16+
+ char const *cwd = getcwd(buf, size);
17+
pthread_mutex_lock(&_lock);
18+
+ if (buf == NULL) {
19+
+ buf = strdup(cwd);
20+
+ }
21+
strlcpy(buf, rewrite_path_rev(buf), size);
22+
buf;
23+
ENDSUBST

flake.nix

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,31 @@
44
inputs.nixpkgs.url = "nixpkgs/nixos-24.05-small";
55
inputs.fakedir-pkgs.url = "github:nixie-dev/fakedir";
66

7-
outputs = { self, nixpkgs, fakedir-pkgs }: let
8-
systems = [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
9-
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
10-
in {
7+
outputs = { self, nixpkgs, fakedir-pkgs }: {
118
bundlers = {
129
nix-bundle = { program, system }: let
1310
nixpkgs' = nixpkgs.legacyPackages.${system};
14-
fakedir = fakedir-pkgs.packages.${system}.fakedir-universal;
11+
fakedir = fakedir-pkgs.packages.${system}.fakedir.overrideAttrs (old: { patches = [./fakedir-null-buffer.patch]; });
1512
nix-bundle = import self { nixpkgs = nixpkgs'; inherit fakedir; };
1613
script-linux = nixpkgs'.writeScript "startup" ''
1714
#!/bin/sh
18-
.${nix-bundle.nix-user-chroot}/bin/nix-user-chroot -n ./nix -- ${program} "$@"
15+
exec .${nix-bundle.nix-user-chroot}/bin/nix-user-chroot -n ./nix -- "$(dirname ${program})/$(basename "$0")" "$@"
1916
'';
2017
script-darwin = nixpkgs'.writeScript "startup" ''
2118
#!/bin/sh
2219
# use absolute paths so the environment variables don't get reinterpreted after a cd
23-
cur_dir=$(pwd)
24-
export DYLD_INSERT_LIBRARIES="''${cur_dir}/lib/libfakedir.dylib"
20+
__TMPX_DAT_PATH=$(pwd)
21+
cd "''${TMPX_RESTORE_PWD}"
22+
export DYLD_INSERT_LIBRARIES="''${__TMPX_DAT_PATH}/lib/libfakedir.dylib"
2523
export FAKEDIR_PATTERN=/nix
26-
export FAKEDIR_TARGET="''${cur_dir}/nix"
27-
exec .${program} "$@"
24+
export FAKEDIR_TARGET="''${__TMPX_DAT_PATH}/nix"
25+
26+
exec "''${__TMPX_DAT_PATH}$(dirname ${program})/$(basename "$0")" "$@"
2827
'';
2928
script = if nixpkgs'.stdenv.isDarwin then script-darwin else script-linux;
3029
in nix-bundle.makebootstrap {
3130
targets = [ script ];
32-
startup = ".${builtins.unsafeDiscardStringContext script} '\"$@\"'";
31+
startup = script;
3332
};
3433
};
3534

0 commit comments

Comments
 (0)