summaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
authorReepca Russelstein <reepca@russelstein.xyz>2025-11-06 13:50:34 -0600
committerLudovic Courtès <ludo@gnu.org>2026-05-27 18:25:16 +0200
commitf519ddf7330f6dd05c880f0135336a8e9d9ca026 (patch)
tree5a53de837beff50f72d4c1f76931ed943bcf390e /nix
parent4ac91ee39c0980c523455ad5329f45f05961b44a (diff)
daemon: Allow ADDR_NO_RANDOMIZE to be omitted if `--allow-aslr'.
Docker's default seccomp filter prevents use of the ADDR_NO_RANDOMIZE flag with the personality system call. It causes personality to return EPERM. In general, we assume that any result other than the only documented one, EINVAL, is caused by seccomp. If we detect that ADDR_NO_RANDOMIZE is blocked, and the --allow-aslr option was passed, we simply don't use it. This allows guix-daemon to continue to work even in these containers, without any implicit weakening of reproducibility. Since it is presumably desirable to be able to build guix itself in such an environment, also pass --allow-aslr to guix-daemon in test-env. * nix/libstore/globals.hh (Settings::allowASLR): new field. * nix/nix-daemon/guix-daemon.cc (options): add --allow-aslr option. (parse_opt): use it to set Settings::allowASLR. * nix/libstore/build.cc (DerivationGoal::startBuilder): detect when ADDR_NO_RANDOMIZE is blocked and --allow-aslr is passed and don't use it in that case. * doc/guix.texi: document --allow-aslr in "Invoking guix-daemon". * build-aux/test-env.in: always pass --allow-aslr. Fixes: guix/guix#3917 Change-Id: I51c5899a9559e161f9e107c2e6a36df395ab3134 Signed-off-by: Ludovic Courtès <ludo@gnu.org> Modified-by: Ludovic Courtès <ludo@gnu.org> Merges: #4616
Diffstat (limited to 'nix')
-rw-r--r--nix/libstore/build.cc25
-rw-r--r--nix/libstore/globals.cc1
-rw-r--r--nix/libstore/globals.hh4
-rw-r--r--nix/nix-daemon/guix-daemon.cc12
4 files changed, 40 insertions, 2 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 7dd630cc5d8..e72a0165987 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -2526,8 +2526,29 @@ void DerivationGoal::startBuilder()
2526 ctx.persona |= 0x0020000; /* == UNAME26 */ 2526 ctx.persona |= 0x0020000; /* == UNAME26 */
2527 } 2527 }
2528 2528
2529 /* Disable address space randomization for improved determinism. */ 2529 /* Check whether we can set ADDR_NO_RANDOMIZE, some container seccomp
2530 ctx.persona |= ADDR_NO_RANDOMIZE; 2530 policies block it. */
2531 int currentPersonality = personality(0xffffffff);
2532 if (currentPersonality == -1)
2533 throw SysError("unable to get current personality");
2534
2535 if (personality(currentPersonality | ADDR_NO_RANDOMIZE) == -1) {
2536 if (errno == EINVAL)
2537 throw SysError("unexpectedly unable to add ADDR_NO_RANDOMIZE to personality");
2538
2539 /* Some other, unexpected errno; seccomp is probably behind it. */
2540 if (!settings.allowASLR)
2541 throw SysError("ADDR_NO_RANDOMIZE appears blocked and `--allow-aslr' was not passed, refusing to weaken reproducibility by default");
2542
2543 printMsg(lvlInfo, "the ADDR_NO_RANDOMIZE personality flag appears to be blocked, not using it");
2544 }
2545 else {
2546 /* It worked, now first restore the original personality. */
2547 if (personality(currentPersonality) == -1)
2548 throw SysError("unable to restore personality after testing for availability of ADDR_NO_RANDOMIZE");
2549 /* Disable address space randomization for improved determinism. */
2550 ctx.persona |= ADDR_NO_RANDOMIZE;
2551 }
2531 2552
2532#endif 2553#endif
2533 2554
diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc
index eb7e7dac413..aa808186bd0 100644
--- a/nix/libstore/globals.cc
+++ b/nix/libstore/globals.cc
@@ -53,6 +53,7 @@ Settings::Settings()
53 showTrace = false; 53 showTrace = false;
54 useHostLoopback = true; 54 useHostLoopback = true;
55 slirp4netns = SLIRP4NETNS; 55 slirp4netns = SLIRP4NETNS;
56 allowASLR = false;
56} 57}
57 58
58 59
diff --git a/nix/libstore/globals.hh b/nix/libstore/globals.hh
index 8ce8aa665a8..f6b856091fc 100644
--- a/nix/libstore/globals.hh
+++ b/nix/libstore/globals.hh
@@ -213,6 +213,10 @@ struct Settings {
213 /* The filename to use for executing slirp4netns when it is needed. */ 213 /* The filename to use for executing slirp4netns when it is needed. */
214 Path slirp4netns; 214 Path slirp4netns;
215 215
216 /* Whether to proceed without the ADDR_NO_RANDOMIZE personality flag if
217 * its use is blocked. */
218 bool allowASLR;
219
216private: 220private:
217 SettingsMap settings; 221 SettingsMap settings;
218 222
diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc
index 58a6f3eba45..edbec81c43c 100644
--- a/nix/nix-daemon/guix-daemon.cc
+++ b/nix/nix-daemon/guix-daemon.cc
@@ -85,6 +85,7 @@ builds derivations on behalf of its clients.");
85#define GUIX_OPT_LOG_COMPRESSION 20 85#define GUIX_OPT_LOG_COMPRESSION 20
86#define GUIX_OPT_DISCOVER 21 86#define GUIX_OPT_DISCOVER 21
87#define GUIX_OPT_ISOLATE_HOST_LOOPBACK 22 87#define GUIX_OPT_ISOLATE_HOST_LOOPBACK 22
88#define GUIX_OPT_ALLOW_ASLR 23
88 89
89static const struct argp_option options[] = 90static const struct argp_option options[] =
90 { 91 {
@@ -157,6 +158,14 @@ to live outputs") },
157 n_("produce debugging output") }, 158 n_("produce debugging output") },
158 { "isolate-host-loopback", GUIX_OPT_ISOLATE_HOST_LOOPBACK, 0, 0, 159 { "isolate-host-loopback", GUIX_OPT_ISOLATE_HOST_LOOPBACK, 0, 0,
159 n_("do not allow fixed-output chroot builds to access the host loopback") }, 160 n_("do not allow fixed-output chroot builds to access the host loopback") },
161 { "allow-aslr", GUIX_OPT_ALLOW_ASLR, 0,
162#ifdef HAVE_SYS_PERSONALITY_H
163 0,
164#else
165 OPTION_HIDDEN,
166#endif
167 n_("allow builds to start even if address space layout \
168randomization (ASLR) cannot be disabled")},
160 { 0, 0, 0, 0, 0 } 169 { 0, 0, 0, 0, 0 }
161 }; 170 };
162 171
@@ -292,6 +301,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
292 case GUIX_OPT_ISOLATE_HOST_LOOPBACK: 301 case GUIX_OPT_ISOLATE_HOST_LOOPBACK:
293 settings.useHostLoopback = false; 302 settings.useHostLoopback = false;
294 break; 303 break;
304 case GUIX_OPT_ALLOW_ASLR:
305 settings.allowASLR = true;
306 break;
295 default: 307 default:
296 return (error_t) ARGP_ERR_UNKNOWN; 308 return (error_t) ARGP_ERR_UNKNOWN;
297 } 309 }