[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#63904: Can't setuid programs to anybody but root
From: |
Edouard Klein |
Subject: |
bug#63904: Can't setuid programs to anybody but root |
Date: |
Tue, 06 Jun 2023 09:21:43 +0200 |
User-agent: |
mu4e 1.8.13; emacs 28.2 |
Dear Guix, CCing the core team,
I tried tracking down the bug.
The fatidic call to getpw was easy enough to find:
The make-setuid-program procedure is given a numeric uid argument. This
numeric uid is found from the user name string by
activate-setuid-program which calls getpwnam
(gnu/build/activation.scm:317).
Now this gave me an idea to sidestep the bug: See below the modified
part of the minimal reproductible example: I just force-assign a uid to
the user I want to setuid to, and give this uid instead of the username
to the setuid record.
This is cumbersome, but it does the job: the call to getpw is averted
and I get a system in which I can setuid to somebody other than root.
However, I'm lost as to how to solve the bug for good. I tried to
understand the call stack, but I can't figure out how in the folding
service machinery the services are ordered. My intuition is that I need
to make it so the folding of non-root setuids happen after the folding
of user and groups (I also have the intuition that root-setuids must
happen before, because folding users and group may require that root
setuid binaries are there, but I have not been able to verify that).
Here is what I was able to find.
getpw is called by activate-setuid-program
activate-setuid-program is called in setuid-program->activation-gexp
setuid-program->activation-gexp is the activation procedure for
setuid-program-service-type
setuid-program-service-type is itself an extension of activation-service-type
I'm trying to follow how the service DAG is constructed, and then
walked, from there, but I don't think I have a very clear model of how
it works in my head.
I think the devil may be in:
(define (compute-boot-script _ gexps)
;; Reverse GEXPS so that extensions appear in the boot script in the right
;; order. That is, user extensions would come first, and extensions added
;; by 'essential-services' (e.g., running shepherd) are guaranteed to come
;; last.
(gexp->file "boot"
;; Clean up and activate the system, then spawn shepherd.
#~(begin #$@(reverse gexps))))
Any help there would be greatly appreciated.
Thanks in advance,
Cheers,
Edouard.
(operating-system
(host-name "minimal-container")
(timezone "UTC")
(locale "en_US.utf8")
(bootloader (bootloader-configuration
(bootloader grub-bootloader)))
(file-systems %base-file-systems)
(users (cons
(user-account
(name "suc")
(group "users")
(uid 1042))
%base-user-accounts))
(setuid-programs
(cons (setuid-program (program (file-append coreutils "/bin/true"))
;; (user "suc")
(user 1042)
)
%setuid-programs))
(packages %base-packages)
(services %base-services))
edk@beaver-labs.com writes:
> Dear Guix developers,
>
> At the end of the email is the code for a minimal container, which tries
> to setuid =true=, the simplest binary of all, to user suc.
>
> When line 26 is commented, and the container is built and run with:
> sudo $(guix system container mwe.scm)
>
> One can login to the container and run:
> ls -l /run/setuid-programs/true
>
> which yields:
> -r-sr-xr-x 1 root root 39488 Jun 5 09:59 /run/setuid-programs/true
> as it should.
>
> Also, one can fire up guile and run (getpw "suc") and get in return:
> $1 = #("suc" "x" 1000 998 "" "/home/suc"
> "/gnu/store/m6c5hgqg569mbcjjbp8l8m7q82ascpdl-bash-5.1.16/bin/bash")
>
> However, when line 26 is uncommented, the container can be built, but
> when run fails with the error below.
> My hunch is that things are done out of order, with setuid binaries
> being set up before user creation, but I have no way of checking that.
>
> Please do not hesitate to ping me if I can be of help.
>
> Cheers,
>
> Edouard.
>
> The error:
> system container is running as PID 9825
> WARNING: (guile-user): imported module (guix build utils) overrides core
> binding `delete'
> Run 'sudo guix container exec 9825 /run/current-system/profile/bin/bash
> --login'
> or run 'sudo nsenter -a -t 9825' to get a shell into it.
>
> WARNING: (guile-user): imported module (guix build utils) overrides core
> binding `delete'
> making '/gnu/store/mnc9lfpn01frmffqa31jy3c381dkgrwl-system' the current
> system...
> WARNING: (guile-user): imported module (guix build utils) overrides core
> binding `delete'
> setting up setuid programs in '/run/setuid-programs'...
> Backtrace:
> 12 (primitive-load "/gnu/store/bygckv7p4091xqykjnkay4qnazn…")
> In gnu/build/linux-container.scm:
> 300:8 11 (call-with-temporary-directory #<procedure 7fb026898d70…>)
> 397:16 10 (_ "/tmp/guix-directory.B9dmTN")
> 62:6 9 (call-with-clean-exit #<procedure 7fb0268a5380 at gnu/b…>)
> In unknown file:
> 8 (primitive-load "/gnu/store/mnc9lfpn01frmffqa31jy3c381d…")
> In ice-9/eval.scm:
> 619:8 7 (_ #f)
> In unknown file:
> 6 (primitive-load "/gnu/store/dib6wfh2r52dfaydz78n33267qx…")
> In srfi/srfi-1.scm:
> 634:9 5 (for-each #<procedure primitive-load (_)> ("/gnu/sto…" …))
> In unknown file:
> 4 (primitive-load "/gnu/store/ypwqsx11k2qmxkscmzan6srq87q…")
> In srfi/srfi-1.scm:
> 634:9 3 (for-each #<procedure 7fb026380538 at gnu/build/activa…> …)
> In ice-9/boot-9.scm:
> 1747:15 2 (with-exception-handler #<procedure 7fb02683c6f0 at ic…> …)
> In gnu/build/activation.scm:
> 317:57 1 (_)
> In unknown file:
> 0 (getpw "suc")
>
> ERROR: In procedure getpw:
> In procedure getpw: entry not found
>
>
>
> The code
>
> (use-modules
> (guix gexp)
> (gnu system)
> (gnu bootloader)
> (gnu bootloader grub)
> (gnu system file-systems)
> (gnu services)
> (gnu services base)
> (gnu system setuid)
> (gnu packages base))
>
> (operating-system
> (host-name "minimal-container")
> (timezone "UTC")
> (locale "en_US.utf8")
> (bootloader (bootloader-configuration
> (bootloader grub-bootloader)))
> (file-systems %base-file-systems)
> (users (cons
> (user-account
> (name "suc")
> (group "users"))
> %base-user-accounts))
> (setuid-programs
> (cons (setuid-program (program (file-append coreutils "/bin/true"))
> (user "suc")
> )
> %setuid-programs))
> (packages %base-packages)
> (services %base-services))