Subject: Re: [bug#75810] [PATCH 0/6] Rootless guix-daemon

From: Ludovic Courtès <[email-masked]>
Date: Fri, 14 Mar 2025 00:51:28 +0100

Hey,

Reepca Russelstein <[email-masked]> skribis:

> I failed to take into account that the setns sequence needs to start by
> joining the user namespace that owns all the other namespaces, so as to
> gain the necessary capabilities for joining them.  But after unshare
> creates the second user namespace, that first user namespace no longer
> has a process in it; it only still exists due to indirect references.
> Without a process to reference it by, we can't join it.  Trying to join
> the user namespace of the builder instead joins the inner user
> namespace, then tries to use the acquired credentials to join the
> namespaces owned by the outer user namespace, which naturally fails.

I see; brilliant.

>> If you can think of ways to do that, I’m all ears.  :-)
>
> It looks like the only easy way to test this - aside from something like
> scripted gdb playthroughs - might legitimately be to include a test
> inside the daemon itself.

Yes, that makes sense.

I added a ‘umount’ call, checking that we get EINVAL, and confirmed that
this check fails if we comment out the ‘unshare’ call.

I pushed the updated branch to Codeberg.  There are test failures in the
‘debian-install’ test that I now need to investigate before I send v5,
notably CAP_SYS_CHOWN not working (?) when attempting to create root’s
profile:

--8<---------------cut here---------------start------------->8---
guix install: [1;31merror: [0mdirectory `/var/guix/profiles/per-user/root' is not owned by you
[1;36mhint: [0mPlease change the owner of `/var/guix/profiles/per-user/root' to user
"root".

ls: cannot access '/root/.guix-profile': No such file or directory
sh: 1: /root/.guix-profile/bin/hello: not found
[…]
PASS: marionette works
PASS: /etc/os-release
PASS: mount host file store
PASS: screenshot before
PASS: install fake dependencies
PASS: run install script
PASS: create user account
PASS: guix describe
PASS: hello not already built
PASS: guix build hello
PASS: hello indeed built
/gnu/store/59qdz41chhifidaq79iiiyx70m7lmyrp-debian-install-builder:1: FAIL guix install hello
/gnu/store/59qdz41chhifidaq79iiiyx70m7lmyrp-debian-install-builder:1: FAIL user profile created
/gnu/store/59qdz41chhifidaq79iiiyx70m7lmyrp-debian-install-builder:1: FAIL hello
PASS: guix install hello, unprivileged user
PASS: user hello
PASS: unprivileged user profile created
/gnu/store/59qdz41chhifidaq79iiiyx70m7lmyrp-debian-install-builder:1: FAIL store is read-only
PASS: screenshot after
# of expected passes      15
# of unexpected failures  4
--8<---------------cut here---------------end--------------->8---

Ludo’.