mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-25 22:08:16 -05:00
services: Prevent following symlinks during activation.
This addresses a potential security issue, where a compromised service could trick the activation code in changing the permissions, owner and group of arbitrary files. However, this patch is currently only a partial fix, due to a TOCTTOU (time-of-check to time-of-use) race, which can be fixed once guile has bindings to openat and friends. Fixes: <https://lists.gnu.org/archive/html/guix-devel/2021-01/msg00388.html> * gnu/build/activation.scm: new procedure 'mkdir-p/perms'. * gnu/services/authentication.scm (%nslcd-activation, nslcd-service-type): use new procedure. * gnu/services/cups.scm (%cups-activation): likewise. * gnu/services/dbus.scm (dbus-activation): likewise. * gnu/services/dns.scm (knot-activation): likewise. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
1a1d0fe505
commit
520bac7ed0
5 changed files with 96 additions and 45 deletions
|
@ -1,6 +1,11 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
|
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
|
;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
|
||||||
|
;;; Copyright © 2015, 2018 Mark H Weaver <mhw@netris.org>
|
||||||
|
;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
|
||||||
|
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -37,7 +42,8 @@ (define-module (gnu build activation)
|
||||||
activate-modprobe
|
activate-modprobe
|
||||||
activate-firmware
|
activate-firmware
|
||||||
activate-ptrace-attach
|
activate-ptrace-attach
|
||||||
activate-current-system))
|
activate-current-system
|
||||||
|
mkdir-p/perms))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
|
@ -55,6 +61,47 @@ (define %skeleton-directory
|
||||||
(define (dot-or-dot-dot? file)
|
(define (dot-or-dot-dot? file)
|
||||||
(member file '("." "..")))
|
(member file '("." "..")))
|
||||||
|
|
||||||
|
;; Based upon mkdir-p from (guix build utils)
|
||||||
|
(define (verify-not-symbolic dir)
|
||||||
|
"Verify DIR or its ancestors aren't symbolic links."
|
||||||
|
(define absolute?
|
||||||
|
(string-prefix? "/" dir))
|
||||||
|
|
||||||
|
(define not-slash
|
||||||
|
(char-set-complement (char-set #\/)))
|
||||||
|
|
||||||
|
(define (verify-component file)
|
||||||
|
(unless (eq? 'directory (stat:type (lstat file)))
|
||||||
|
(error "file name component is not a directory" dir)))
|
||||||
|
|
||||||
|
(let loop ((components (string-tokenize dir not-slash))
|
||||||
|
(root (if absolute?
|
||||||
|
""
|
||||||
|
".")))
|
||||||
|
(match components
|
||||||
|
((head tail ...)
|
||||||
|
(let ((file (string-append root "/" head)))
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
(verify-component file)
|
||||||
|
(loop tail file))
|
||||||
|
(lambda args
|
||||||
|
(if (= ENOENT (system-error-errno args))
|
||||||
|
#t
|
||||||
|
(apply throw args))))))
|
||||||
|
(() #t))))
|
||||||
|
|
||||||
|
;; TODO: the TOCTTOU race can be addressed once guile has bindings
|
||||||
|
;; for fstatat, openat and friends.
|
||||||
|
(define (mkdir-p/perms directory owner bits)
|
||||||
|
"Create the directory DIRECTORY and all its ancestors.
|
||||||
|
Verify no component of DIRECTORY is a symbolic link.
|
||||||
|
Warning: this is currently suspect to a TOCTTOU race!"
|
||||||
|
(verify-not-symbolic directory)
|
||||||
|
(mkdir-p directory)
|
||||||
|
(chown directory (passwd:uid owner) (passwd:gid owner))
|
||||||
|
(chmod directory bits))
|
||||||
|
|
||||||
(define* (copy-account-skeletons home
|
(define* (copy-account-skeletons home
|
||||||
#:key
|
#:key
|
||||||
(directory %skeleton-directory)
|
(directory %skeleton-directory)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
|
;;; Copyright © 2018 Danny Milosavljevic <dannym@scratchpost.org>
|
||||||
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -31,6 +32,7 @@ (define-module (gnu services authentication)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
|
#:use-module (guix modules)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
|
@ -521,6 +523,16 @@ (module pam-ldap-module))))
|
||||||
(define (pam-ldap-pam-services config)
|
(define (pam-ldap-pam-services config)
|
||||||
(list (pam-ldap-pam-service config)))
|
(list (pam-ldap-pam-service config)))
|
||||||
|
|
||||||
|
(define %nslcd-activation
|
||||||
|
(with-imported-modules (source-module-closure '((gnu build activation)))
|
||||||
|
#~(begin
|
||||||
|
(use-modules (gnu build activation))
|
||||||
|
(let ((rundir "/var/run/nslcd")
|
||||||
|
(user (getpwnam "nslcd")))
|
||||||
|
(mkdir-p/perms rundir user #o755)
|
||||||
|
(when (file-exists? "/etc/nslcd.conf")
|
||||||
|
(chmod "/etc/nslcd.conf" #o400))))))
|
||||||
|
|
||||||
(define nslcd-service-type
|
(define nslcd-service-type
|
||||||
(service-type
|
(service-type
|
||||||
(name 'nslcd)
|
(name 'nslcd)
|
||||||
|
@ -531,15 +543,7 @@ (define nslcd-service-type
|
||||||
(service-extension etc-service-type
|
(service-extension etc-service-type
|
||||||
nslcd-etc-service)
|
nslcd-etc-service)
|
||||||
(service-extension activation-service-type
|
(service-extension activation-service-type
|
||||||
(const #~(begin
|
(const %nslcd-activation))
|
||||||
(use-modules (guix build utils))
|
|
||||||
(let ((rundir "/var/run/nslcd")
|
|
||||||
(user (getpwnam "nslcd")))
|
|
||||||
(mkdir-p rundir)
|
|
||||||
(chown rundir (passwd:uid user) (passwd:gid user))
|
|
||||||
(chmod rundir #o755)
|
|
||||||
(when (file-exists? "/etc/nslcd.conf")
|
|
||||||
(chmod "/etc/nslcd.conf" #o400))))))
|
|
||||||
(service-extension pam-root-service-type
|
(service-extension pam-root-service-type
|
||||||
pam-ldap-pam-services)
|
pam-ldap-pam-services)
|
||||||
(service-extension nscd-service-type
|
(service-extension nscd-service-type
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
|
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
|
||||||
;;; Copyright © 2019 Alex Griffin <a@ajgrf.com>
|
;;; Copyright © 2019 Alex Griffin <a@ajgrf.com>
|
||||||
;;; Copyright © 2019 Tobias Geerinckx-Rice <me@tobias.gr>
|
;;; Copyright © 2019 Tobias Geerinckx-Rice <me@tobias.gr>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -31,6 +32,7 @@ (define-module (gnu services cups)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
|
#:use-module (guix modules)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module ((srfi srfi-1) #:select (append-map find))
|
#:use-module ((srfi srfi-1) #:select (append-map find))
|
||||||
#:export (cups-service-type
|
#:export (cups-service-type
|
||||||
|
@ -871,13 +873,11 @@ (define-configuration opaque-cups-configuration
|
||||||
|
|
||||||
(define %cups-activation
|
(define %cups-activation
|
||||||
;; Activation gexp.
|
;; Activation gexp.
|
||||||
(with-imported-modules '((guix build utils))
|
(with-imported-modules (source-module-closure '((gnu build activation)
|
||||||
|
(guix build utils)))
|
||||||
#~(begin
|
#~(begin
|
||||||
(use-modules (guix build utils))
|
(use-modules (gnu build activation)
|
||||||
(define (mkdir-p/perms directory owner perms)
|
(guix build utils))
|
||||||
(mkdir-p directory)
|
|
||||||
(chown directory (passwd:uid owner) (passwd:gid owner))
|
|
||||||
(chmod directory perms))
|
|
||||||
(define (build-subject parameters)
|
(define (build-subject parameters)
|
||||||
(string-concatenate
|
(string-concatenate
|
||||||
(map (lambda (pair)
|
(map (lambda (pair)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
|
;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -28,6 +29,7 @@ (define-module (gnu services dbus)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:use-module ((guix packages) #:select (package-name))
|
#:use-module ((guix packages) #:select (package-name))
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
|
#:use-module (guix modules)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:export (dbus-configuration
|
#:export (dbus-configuration
|
||||||
|
@ -161,24 +163,23 @@ (define dbus-setuid-programs
|
||||||
|
|
||||||
(define (dbus-activation config)
|
(define (dbus-activation config)
|
||||||
"Return an activation gexp for D-Bus using @var{config}."
|
"Return an activation gexp for D-Bus using @var{config}."
|
||||||
|
(with-imported-modules (source-module-closure
|
||||||
|
'((gnu build activation)
|
||||||
|
(guix build utils)))
|
||||||
#~(begin
|
#~(begin
|
||||||
(use-modules (guix build utils))
|
(use-modules (gnu build activation)
|
||||||
|
(guix build utils))
|
||||||
(mkdir-p "/var/run/dbus")
|
|
||||||
|
|
||||||
(let ((user (getpwnam "messagebus")))
|
(let ((user (getpwnam "messagebus")))
|
||||||
(chown "/var/run/dbus"
|
|
||||||
(passwd:uid user) (passwd:gid user))
|
|
||||||
|
|
||||||
;; This directory contains the daemon's socket so it must be
|
;; This directory contains the daemon's socket so it must be
|
||||||
;; world-readable.
|
;; world-readable.
|
||||||
(chmod "/var/run/dbus" #o755))
|
(mkdir-p/perms "/var/run/dbus" user #o755))
|
||||||
|
|
||||||
(unless (file-exists? "/etc/machine-id")
|
(unless (file-exists? "/etc/machine-id")
|
||||||
(format #t "creating /etc/machine-id...~%")
|
(format #t "creating /etc/machine-id...~%")
|
||||||
(invoke (string-append #$(dbus-configuration-dbus config)
|
(invoke (string-append #$(dbus-configuration-dbus config)
|
||||||
"/bin/dbus-uuidgen")
|
"/bin/dbus-uuidgen")
|
||||||
"--ensure=/etc/machine-id"))))
|
"--ensure=/etc/machine-id")))))
|
||||||
|
|
||||||
(define dbus-shepherd-service
|
(define dbus-shepherd-service
|
||||||
(match-lambda
|
(match-lambda
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
;;; Copyright © 2017 Julien Lepiller <julien@lepiller.eu>
|
;;; Copyright © 2017 Julien Lepiller <julien@lepiller.eu>
|
||||||
;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
|
;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
|
||||||
;;; Copyright © 2020 Pierre Langlois <pierre.langlois@gmx.com>
|
;;; Copyright © 2020 Pierre Langlois <pierre.langlois@gmx.com>
|
||||||
|
;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -28,6 +29,7 @@ (define-module (gnu services dns)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
|
#:use-module (guix modules)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
#:use-module (srfi srfi-34)
|
#:use-module (srfi srfi-34)
|
||||||
|
@ -607,17 +609,14 @@ (define %knot-accounts
|
||||||
(shell (file-append shadow "/sbin/nologin")))))
|
(shell (file-append shadow "/sbin/nologin")))))
|
||||||
|
|
||||||
(define (knot-activation config)
|
(define (knot-activation config)
|
||||||
|
(with-imported-modules (source-module-closure '((gnu build activation)))
|
||||||
#~(begin
|
#~(begin
|
||||||
(use-modules (guix build utils))
|
(use-modules (gnu build activation))
|
||||||
(define (mkdir-p/perms directory owner perms)
|
|
||||||
(mkdir-p directory)
|
|
||||||
(chown directory (passwd:uid owner) (passwd:gid owner))
|
|
||||||
(chmod directory perms))
|
|
||||||
(mkdir-p/perms #$(knot-configuration-run-directory config)
|
(mkdir-p/perms #$(knot-configuration-run-directory config)
|
||||||
(getpwnam "knot") #o755)
|
(getpwnam "knot") #o755)
|
||||||
(mkdir-p/perms "/var/lib/knot" (getpwnam "knot") #o755)
|
(mkdir-p/perms "/var/lib/knot" (getpwnam "knot") #o755)
|
||||||
(mkdir-p/perms "/var/lib/knot/keys" (getpwnam "knot") #o755)
|
(mkdir-p/perms "/var/lib/knot/keys" (getpwnam "knot") #o755)
|
||||||
(mkdir-p/perms "/var/lib/knot/keys/keys" (getpwnam "knot") #o755)))
|
(mkdir-p/perms "/var/lib/knot/keys/keys" (getpwnam "knot") #o755))))
|
||||||
|
|
||||||
(define (knot-shepherd-service config)
|
(define (knot-shepherd-service config)
|
||||||
(let* ((config-file (knot-config-file config))
|
(let* ((config-file (knot-config-file config))
|
||||||
|
|
Loading…
Reference in a new issue