diff options
author | Ludovic Courtès <ludovic.courtes@inria.fr> | 2025-01-22 23:40:24 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2025-03-26 17:57:43 +0100 |
commit | ae18b3d9e6bd0c184505a094851448d08555e23e (patch) | |
tree | 4c7359dfea08e58d7926af2097ed305e5a686ab9 /tests | |
parent | 40f69b586a440d0397fa3dfe03b95a0f44e4d242 (diff) |
daemon: Allow running as non-root with unprivileged user namespaces.
Many thanks to Reepca Russelstein for their review and guidance on these
changes.
* nix/libstore/build.cc (guestUID, guestGID): New variables.
(DerivationGoal)[readiness]: New field.
(initializeUserNamespace): New function.
(DerivationGoal::runChild): When ‘readiness.readSide’ is positive, read
from it.
(DerivationGoal::startBuilder): Call ‘chown’
only when ‘buildUser.enabled()’ is true. Pass CLONE_NEWUSER to ‘clone’
when ‘buildUser.enabled()’ is false or not running as root. Retry
‘clone’ without CLONE_NEWUSER upon EPERM.
(DerivationGoal::registerOutputs): Make ‘actualPath’ writable before
‘rename’.
(DerivationGoal::deleteTmpDir): Catch ‘SysError’ around ‘_chown’ call.
* nix/libstore/local-store.cc (LocalStore::createUser): Do nothing if
‘dirs’ already exists. Warn instead of failing when failing to chown
‘dir’.
* guix/substitutes.scm (%narinfo-cache-directory): Check for
‘_NIX_OPTIONS’ rather than getuid() == 0 to determine the cache
location.
* doc/guix.texi (Build Environment Setup): Reorganize a bit. Add
section headings “Daemon Running as Root” and “The Isolated Build
Environment”. Add “Daemon Running Without Privileges” subsection.
Remove paragraph about ‘--disable-chroot’.
(Invoking guix-daemon): Warn against ‘--disable-chroot’ and explain why.
* tests/derivations.scm ("builder is outside the store"): New test.
Reviewed-by: Reepca Russelstein <reepca@russelstein.xyz>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/derivations.scm | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/tests/derivations.scm b/tests/derivations.scm index 72ea9aa9cc..b0b151dd33 100644 --- a/tests/derivations.scm +++ b/tests/derivations.scm @@ -858,6 +858,20 @@ (call-with-input-file (derivation->output-path drv) get-string-all)))) +(test-assert "builder is outside the store" + ;; Ensure that attempts to build derivations whose builder is outside the + ;; store are rejected. This is a protection against attacks similar to + ;; CVE-2019-5736, which abuse the fact that /proc/self/exe can be opened + ;; even when it presents itself as a symlink to a file not in the chroot. + (let* ((builder (add-file-tree-to-store %store + `("builder" symlink "/proc/self/exe"))) + (drv (derivation %store "attempt-to-run-guix-daemon" builder '() + #:env-vars + '(("LD_PRELOAD" . "attacker-controlled.so"))))) + (guard (c ((store-protocol-error? c) c)) + (build-derivations %store (list drv)) + #f))) + (define %coreutils (false-if-exception |