Subject: bug#73925: closed (Re: [bug#73925] [PATCH] add access control to daemon socket in shepherd service)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 03 Nov 2024 22:07:02 +0000

Your bug report

#73925: [PATCH] add access control to daemon socket in shepherd service

which was filed against the guix-patches package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
73925: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=73925
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: [bug#73925] [PATCH] add access control to daemon socket in shepherd service
From: Ludovic Courtès <[email-masked]>
To: Reepca Russelstein <[email-masked]>
Cc: [email-masked]
Date: Sun, 03 Nov 2024 23:05:46 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Reepca Russelstein <[email-masked]> skribis:

> From b8ea0288a35c27912580bd7fe861dd6e497f4c33 Mon Sep 17 00:00:00 2001
> Message-ID: <[email-masked]>
> From: Reepca Russelstein <[email-masked]>
> Date: Sat, 19 Oct 2024 22:43:27 -0500
> Subject: [PATCH] services: guix-configuration: add access control to daemon
>  socket.
>
> * gnu/services/base.scm
>   (guix-configuration-socket-directory-{permissions,group,user}): new fields.
>   (guix-shepherd-service): use them.
> * doc/guix.texi: document them.
>
> Change-Id: I8f4c2e20392ced47c09812e62903c87cc0f4a97a

Applied, thanks!

Subject: [PATCH] add access control to daemon socket in shepherd service
From: Reepca Russelstein <[email-masked]>
To: [email-masked]
Date: Sun, 20 Oct 2024 18:31:31 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

Passing "--disable-chroot" to guix-daemon makes it possible for the
build users to be taken over by anybody who can start a build: they need
only cause a builder to put a setuid binary in /tmp.  That being said,
there are some situations where it currently can't be avoided, like on
Hurd.  It would also probably be good to have the ability to harden a
guix daemon in general by restricting access to it.  For example,
there's no reason that the ntpd user needs access to the guix daemon
(note that this is distinct from access to the *store*, which is of
course always world-readable).

The attached patch implements that restriction for users of
guix-service-type by limiting access to /var/guix/daemon-socket in
accordance with the user-supplied permissions, user, and group.

Example usage:

------------------------------------
;; Limit access to the guix-daemon socket to members of the "users"
;; group
(modify-services %desktop-services
  (guix-service-type config =>
                     (guix-configuration
                      (inherit config)
                      (socket-directory-perms #o750)
                      (socket-directory-group "users"))))
------------------------------------

- reepca
From b5163889efb544cfe83cd2bcb3ebd3a957c95a18 Mon Sep 17 00:00:00 2001
Message-ID: <[email-masked]>
From: Reepca Russelstein <[email-masked]>
Date: Sat, 19 Oct 2024 22:43:27 -0500
Subject: [PATCH] services: guix-configuration: add access control to daemon
 socket.

* gnu/services/base.scm
  (guix-configuration-socket-directory-{perms,group,user}): new fields.
  (guix-shepherd-service): use them.
* doc/guix.texi: document them.

Change-Id: Ic228377b25a83692b0c637dafbd03c4609e332fc
---
 doc/guix.texi         | 15 +++++++++++++++
 gnu/services/base.scm | 43 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index cb758f9005..0e387f0a17 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -19775,6 +19775,21 @@ Base Services
 Environment variables to be set before starting the daemon, as a list of
 @code{key=value} strings.
 
+@item @code{socket-directory-perms} (default: @code{#o755})
+Permissions to set for the directory @file{/var/guix/daemon-socket}.
+This, together with @code{socket-directory-group} and
+@code{socket-directory-user}, determines who can connect to the guix
+daemon via its unix socket.  TCP socket operation is unaffected by
+these.
+
+@item @code{socket-directory-group} (default: @code{#f})
+Group to set for the directory @file{/var/guix/daemon-socket}, or
+@code{#f} to keep its group as root.
+
+@item @code{socket-directory-user} (default: @code{#f})
+User to set for the directory @file{/var/guix/daemon-socket}, or
+@code{#f} to keep its user as root.
+
 @end table
 @end deftp
 
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index fd2cc9d17a..daedc77468 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -1880,7 +1880,13 @@ (define-record-type* <guix-configuration>
   (build-machines   guix-configuration-build-machines ;list of gexps | '()
                     (default '()))
   (environment      guix-configuration-environment  ;list of strings
-                    (default '())))
+                    (default '()))
+  (socket-directory-perms guix-configuration-socket-directory-perms
+                          (default #o755))
+  (socket-directory-group guix-configuration-socket-directory-group
+                          (default #f))
+  (socket-directory-user guix-configuration-socket-directory-user
+                         (default #f)))
 
 (define %default-guix-configuration
   (guix-configuration))
@@ -1941,10 +1947,12 @@ (define (guix-shepherd-service config)
           glibc-utf8-locales)))
 
   (match-record config <guix-configuration>
-    (guix build-group build-accounts authorize-key? authorized-keys
-          use-substitutes? substitute-urls max-silent-time timeout
-          log-compression discover? extra-options log-file
-          http-proxy tmpdir chroot-directories environment)
+                (guix build-group build-accounts authorize-key? authorized-keys
+                      use-substitutes? substitute-urls max-silent-time timeout
+                      log-compression discover? extra-options log-file
+                      http-proxy tmpdir chroot-directories environment
+                      socket-directory-perms socket-directory-group
+                      socket-directory-user)
     (list (shepherd-service
            (documentation "Run the Guix daemon.")
            (provision '(guix-daemon))
@@ -1954,11 +1962,13 @@ (define (guix-shepherd-service config)
                           shepherd-discover-action))
            (modules '((srfi srfi-1)
                       (ice-9 match)
-                      (gnu build shepherd)))
+                      (gnu build shepherd)
+                      (guix build utils)))
            (start
             (with-imported-modules `(((guix config) => ,(make-config.scm))
                                      ,@(source-module-closure
-                                        '((gnu build shepherd))
+                                        '((gnu build shepherd)
+                                          (guix build utils))
                                         #:select? not-config?))
               #~(lambda args
                   (define proxy
@@ -1969,7 +1979,26 @@ (define (guix-shepherd-service config)
                   (define discover?
                     (or (getenv "discover") #$discover?))
 
+                  (mkdir-p "/var/guix")
+                  ;; Ensure that a fresh directory is used, in case the old
+                  ;; one was more permissive and processes have a file
+                  ;; descriptor referencing it hanging around, ready to use
+                  ;; with openat.
+                  (false-if-exception
+                   (delete-file-recursively "/var/guix/daemon-socket"))
+                  (let ((perms #$(logand socket-directory-perms
+                                         (lognot #o022))))
+                    (mkdir "/var/guix/daemon-socket" perms)
+                    ;; Override umask
+                    (chmod "/var/guix/daemon-socket" perms))
+
+                  (let* ((user #$socket-directory-user)
+                         (uid (if user (passwd:uid (getpwnam user)) -1))
+                         (group #$socket-directory-group)
+                         (gid (if group (group:gid (getgrnam group)) -1)))
+                    (chown "/var/guix/daemon-socket" uid gid))
+
                   ;; Start the guix-daemon from a container, when supported,
                   ;; to solve an installation issue. See the comment below for
                   ;; more details.

-- 
2.45.2