~ruther/guix-local

3e2bd2e30bcb183804e853b6cc611387c05712e1 — Ludovic Courtès 2 months ago 55bf53f
services: nscd: Cause PID 1 to drop nscd database mappings on shutdown.

Partly fixes guix/guix#4269.

Fixes a bug whereby shepherd (PID 1) could retain memory mappings for
/var/run/nscd/dbXXX, which are created by glibc’s NSS from database file
descriptors sent by nscd.  Those mappings could then prevent
‘root-file-system’ from re-mounting the root file system as read-write.
This change causes PID 1 to drop these mappings.

PID 1 typically calls libc database functions such as ‘getgr’ when dealing
with AF_UNIX endpoints for socket-activated services, to look up the socket’s
owner and group.  This is where the bug would manifest.

The regression may have been introduced by
85ac164c41fc4c93d3cb2a5d3321c63598c2855f, which caused nscd to handle the
password and group databases.

* gnu/services/base.scm (nscd-shepherd-service): In ‘stop’ procedure, call
‘getpw’, ‘getgr’, and ‘getaddrinfo’.
* gnu/tests/base.scm (run-root-unmount-test) <"open libc NSS database">: New
test.
(%test-root-unmount): Add #:imported-modules.

Change-Id: I197cc8c82165c631f857415898137412ce9bd439
Reported-by: Rutherther <rutherther@ditigal.xyz>
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Merges: #4828
2 files changed, 31 insertions(+), 2 deletions(-)

M gnu/services/base.scm
M gnu/tests/base.scm
M gnu/services/base.scm => gnu/services/base.scm +15 -1
@@ 1557,7 1557,21 @@ the tty to run, among other things."
                                                  (string-append dir "/lib"))
                                                (list #$@name-services))
                                           ":")))))
           (stop #~(make-kill-destructor))
           (stop #~(let ((terminate (make-kill-destructor)))
                     (lambda (process)
                       (terminate process)

                       ;; PID 1 might have mapped nscd database files via
                       ;; '__nscd_get_mapping'.  Call the relevant libc
                       ;; functions (those with a corresponding GETFD* request
                       ;; type) to cause PID 1 to notice that those mappings
                       ;; are stale and to unmap them.  Failure to do so would
                       ;; prevent the root file system from being remounted
                       ;; read-only when shutting down.
                       (false-if-exception (getpw "root"))
                       (false-if-exception (getgr "root"))
                       (false-if-exception (getaddrinfo "localhost" "http"))
                       #f)))
           (modules `((ice-9 popen)               ;for the actions
                      (ice-9 rdelim)
                      (ice-9 match)

M gnu/tests/base.scm => gnu/tests/base.scm +16 -1
@@ 827,6 827,18 @@ in a loop.  See <http://bugs.gnu.org/26931>.")
                                                     ,witness-size))))))
                               marionette))

            ;; Cause PID 1 to create a mapping to nscd's database files.
            ;; Those mappings used to prevent 'root-file-system' to remount
            ;; read-only on shutdown.  See
            ;; <https://codeberg.org/guix/guix/issues/4269>.
            (test-equal "open libc NSS database"
              "root"
              (marionette-eval '(begin
                                  (use-modules (gnu services herd))
                                  (start-service 'nscd) ;wait for nscd
                                  (eval-there '(passwd:name (getgr "root"))))
                               marionette))

            ;; Halt the system.
            (marionette-eval '(system* "/run/current-system/profile/sbin/halt")
                             marionette)


@@ 891,7 903,10 @@ in a loop.  See <http://bugs.gnu.org/26931>.")
    "Make sure the root file system is cleanly unmounted when the system is
halted.")
   (value
    (let ((os (marionette-operating-system %simple-os)))
    (let ((os (marionette-operating-system
               %simple-os
               #:imported-modules '((gnu services herd)
                                    (guix combinators)))))
      (run-root-unmount-test os)))))