diff options
author | Ludovic Courtès <ludo@gnu.org> | 2025-04-08 15:18:04 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2025-04-11 12:18:01 +0200 |
commit | ff5181e27e79c88a82dd429b382e0764af489957 (patch) | |
tree | c810e20eec6135794150d53e0c22df512905963a /tests | |
parent | 13aeb3abf9a8f4a4db1afaacdac275b5b564afdc (diff) |
daemon: Do not make chroot root directory read-only.
Fixes <https://issues.guix.gnu.org/77570>.
Commit 40f69b586a440d0397fa3dfe03b95a0f44e4d242 made chroot root
directory read-only; as a consequence, build processes attempting to
write to the root directory would now get EROFS instead of EACCES.
It turns out that a number of test suites (Go, Ruby, SCons, Shepherd)
would fail because of this observable difference.
To restore previous behavior in build environments while still
preventing build processes from exposing their root directory to outside
processes, this patch (1) keeps the root writable but #o555 by default,
thereby restoring the EACCES behavior, and (2) ensures that the parent
of the chroot root directory is itself user-accessible only.
* nix/libstore/build.cc (class DerivationGoal)[chrootRootTop]: New
field.
(DerivationGoal::startBuilder): Initialize ‘chrootRootTop’ and make it
‘AutoDelete’. Replace ‘mount’ call that made the root directory
read-only by a mere ‘chmod_’ call.
* tests/store.scm ("build root cannot be made world-readable"): Remove.
("writing to build root leads to EACCES"): New test.
Reported-by: Ada Stevenson <adanskana@gmail.com>
Reported-by: keinflue <keinflue@posteo.net>
Suggested-by: Reepca Russelstein <reepca@russelstein.xyz>
Change-Id: I5912e8b3b293f8242a010cfc79255fc981314445
Diffstat (limited to 'tests')
-rw-r--r-- | tests/store.scm | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/tests/store.scm b/tests/store.scm index b1ddff2082..b467314bdc 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -498,32 +498,23 @@ (unless (unprivileged-user-namespace-supported?) (test-skip 1)) -(test-assert "build root cannot be made world-readable" +(test-assert "writing to build root leads to EACCES" (let ((drv (run-with-store %store (gexp->derivation - "attempt-to-make-root-world-readable" - (with-imported-modules (source-module-closure - '((guix build syscalls))) - #~(begin - (use-modules (guix build syscalls)) - - (catch 'system-error - (lambda () - (chmod "/" #o777)) - (lambda args - (format #t "failed to make root writable: ~a~%" - (strerror (system-error-errno args))) - (format #t "attempting read-write remount~%") - (mount "none" "/" "/" (logior MS_BIND MS_REMOUNT)) - (chmod "/" #o777))) + "write-to-root" + #~(begin + (catch 'system-error + (lambda () + (mkdir "/whatever")) + (lambda args + (format #t "mkdir failed, which is good: ~a~%" + (strerror (system-error-errno args))) + (when (= EACCES (system-error-errno args)) + (exit 1)))) - ;; At this point, the build process could create a - ;; world-readable setuid binary under its root (so in the - ;; store) that would remain visible until the build - ;; completes. - (mkdir #$output))))))) - (guard (c ((store-protocol-error? c) #t)) + (mkdir #$output)))))) + (guard (c ((store-protocol-error? c) c)) (build-derivations %store (list drv)) #f))) |