diff options
| author | Reepca Russelstein <reepca@russelstein.xyz> | 2025-11-06 13:50:34 -0600 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2026-05-27 18:25:16 +0200 |
| commit | f519ddf7330f6dd05c880f0135336a8e9d9ca026 (patch) | |
| tree | 5a53de837beff50f72d4c1f76931ed943bcf390e /nix/libstore/build.cc | |
| parent | 4ac91ee39c0980c523455ad5329f45f05961b44a (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/libstore/build.cc')
| -rw-r--r-- | nix/libstore/build.cc | 25 |
1 files changed, 23 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 | ||
