privileged-programs: cant set setuid/setgid to new accounts/groups

  • Open
  • quality assurance status badge
Details
One participant
  • Dariqq
Owner
unassigned
Submitted by
Dariqq
Severity
normal

Debbugs page

D
D
Dariqq wrote on 7 Oct 07:55 -0700
(address . bug-guix@gnu.org)
32a02946-4d85-472c-9035-42cfe3663a3c@posteo.net
Hi,

I was writing a service which (among other things) adds a setuid/setgid
binary for new account+groupn. I got errors and warnings when trying to
instantiate the operating system.


As a reproducer consider this os which tries to privilege the hello
package to a hello user and group (I started this operating system with
guix system container.):

#+begin_src scheme
(use-modules (gnu)
(gnu services))
(use-system-modules privilege shadow)
(use-package-modules base admin)

(define %hello-accounts
(list (user-group (name "hello") (system? #t))
(user-account
(name "hello")
(group "hello")
(system? #t)
(comment "hello user")
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))

(define %hello-privileged
(list
(privileged-program
(program (file-append hello "/bin/hello"))
(setuid? #t)
(setgid? #t)
(user "hello")
(group "hello"))))

(define hello-service-type
(service-type
(name 'hello)
(extensions
(list (service-extension account-service-type
(const %hello-accounts))
(service-extension privileged-program-service-type
(const %hello-privileged))))
(default-value #f)
(description "Hello Reproducer")))


(operating-system
(host-name "hello-test")
(services
(cons (service hello-service-type) %base-services))
(file-systems (cons (file-system
(device (file-system-label "my-root"))
(mount-point "/")
(type "ext4"))
%base-file-systems))
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(targets '("/dev/sda")))))
#+end_src



* when setuid? is #t (regardless of setgid?) I get a fatal error:

setting up privileged programs in '/run/privileged/bin'...
Backtrace:
[...]
In gnu/build/activation.scm:
364:57 1 (_)
In unknown file:
0 (getpw "hello")

ERROR: In procedure getpw:
In procedure getpw: entry not found

Which seems to indicate that the user does not yet exist?

* when setuid? is #f, user field is commented and setgid? #t there is a
nonfatal warning, however privileging fails:

setting up privileged programs in '/run/privileged/bin'...
warning: failed to privilege
"/gnu/store/8bjy9g0cssjrw9ljz2r8ww1sma95isfj-hello-2.12.1/bin/hello": No
such file or directory

When the griup is changed to 0/"root" (the default) things work, i think
because that account already exists.


As another example: the opensmtpd-service-type adds its utilties as
setgid smtpq.

The systemtest is failing with the same error:

From the log
warning: failed to privilege
"/gnu/store/2ng9wzk5d13xcxhk7w7k5zzdm24shk91-opensmtpd-7.5.0p0/sbin/smtpctl":
No such file or directory




However things are very weird because I have the opensmtpd server
running and working locally.

maybe a weird race-condition between account-creation and setting up
privileged programs? Can we ensure that the account creation always
happens before privileged programs are created?
D
D
Dariqq wrote on 7 Oct 13:31 -0700
Re: bug#73680: Acknowledgement (privileged-programs: cant set setuid/setgid to new accounts/groups)
(address . 73680@debbugs.gnu.org)
5c7a4291-cc53-447d-bbc8-33f69788eae8@posteo.net
I have also seen the message when reconfiguring a running system

failed to privilege <binary>: Success

This error seems to come from guiles getgrnam: (used by
activate-privileged-programs to get the gid of a group)

scheme@(guile-user)> (getgrnam "does-not-exist")

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure getgr: Success

Looking at man 3 getgrnam both a 0 or ENOENT return indicate that the
gid was not found. Is /etc/groups being recreated on every boot and
therefore not yet existing upon boot -> ENOENT? When /etc/groups already
exists it returns 0 when not found (which guile interprets as success) ?

I dont know why the getgrnam error is being caught by the (catch
'system-error ... ) and the equally invalid getpwnam is not which lead
me to an unbootable configuration (reconfigure completing because the
user already existed but not yet when ran at boot).


I was looking at the extension-graph and the connection between
privileged-programs and accounts is not being modeled. Not sure how this
should work, because privileged-programs has less information about an
account than account-service.

Still no idea why opensmtpdsetgid is working on my system but when i run
my config through guix system container it does not.
D
D
Dariqq wrote on 8 Oct 03:45 -0700
Re: bug#73680: privileged-programs: cant set setuid/setgid to new accounts/groups
(address . 73680@debbugs.gnu.org)
82936b4e-f572-407a-a98d-1d5771c6ec37@posteo.net
I downloaded the latest iso
to install opensmtpd in there.

After the reconfigure i got the 'failed to privilege <binary>: Success'
warning but upon reboot things were working.

I think I know what is happening now:

The *first* time we try to privilege something it fails because the
group does not yet exist. After a reboot it is succeeeding because it is
using the group info from the previous boot, because that has not been
recreated yet.

This seems to work for groups because the getgrnam error "group does not
exist" is a 'system-error being caught by the exception handler, while
the getpwnam-error "user does not exist" is a 'misc-error instead,
causing a backtrace which aborts further activation scripts (that would
create the user)

As a simple workaround we could catch the getpwnam error too but this is
not really solving anything and relies on previous state which might be
incorrect. This is also really fragile.


Another idea would be to run the account+user creating scripts as early
as possible. Or as a more thorough solution model the dependency on
users/groups directly to enforce the ordering (might be problematic
because some activation scripts also requrie a user/group to set
permissions which would make the extension graph not acyclic (accounts
-> activation -> accounts). Maybe this is doable with a more minimal
accounts service that only knows about users/group names?

I am surprised this has not been causing issues earlier as also a lot of
direct activation-extensions set ownership on directories (that this
works seems like a lucky coincidence in how
service-extension/service-folding works rather than a design consideration).
D
D
Dariqq wrote 6 days ago
(address . 73680@debbugs.gnu.org)
26df374b-5cc8-4512-b276-05df5d4d2b6a@posteo.net
The problem is the ordering of the services which is responsible for the
order in the activation-service-type after folding:


It currently looks something like this (omitting some things)


activation-service
...
account-service
etc-service
...
privileged-program-service

---

which are added to the folded activation-service in reverse order (one
can check this by looking at the service-value of

(fold-services (operating-system-services %os) #:target-type
activation-service-type)


I think the easiest solution would be to either move the
privileged-program-service-type up or the account-service down.


Because activation-service is above account-service users/groups are
already available for direct activation-service extensions that set
permission/ownership on files
D
D
Dariqq wrote 6 days ago
(address . 73680@debbugs.gnu.org)
e2cba688-716e-47e4-8385-25b42a5cb1a7@posteo.net
Regarding the opensmtpd test failure:

THis is completely unrelated to the privileging problem (we invoke the
unprivilegded one which results in a warning but we dont really use it
and only check if mail gets delivered)

THe problem is that we check /var/spool/mail for the mail but opensmtpd
seems to deliver to /var/mail instead.

From the buid log of opensmtpd:
checking system mail directory... /var/mail from _PATH_MAILDIR
D
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 73680@patchwise.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 73680
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch