Subject: [bug#75810] [PATCH v3 00/11] Rootless guix-daemon

From: Ludovic Courtès <[email-masked]>
Date: Fri, 28 Feb 2025 10:43:24 +0100

Hi,

Reepca Russelstein <[email-masked]> skribis:

>>   • Unit files for systemd tweaked so that (1) guix-daemon sees
>>     a private read-write mount of the store, and (2) gnu-store.mount
>>     actually remounts the store read-only after guix-daemon has
>>     started.
>
> I'm not familiar with how systemd does service dependencies, but does
> this mean that the store becomes writable when the daemon is stopped?

I had to check because it’s not crystal clear.

‘systemctl stop guix-daemon’ also stops ‘gnu-store.mount’.

But then you can do ‘systemctl start gnu-store.mount’, which does *not*
start guix-daemon; at that point, ‘systemctl start guix-daemon’ spawns
guix-daemon, but it cannot write to the store.

It’s messy, but I don’t know how to do better.

[...]

> It may work well to use the v2 patch for this with a call to
> secureFilePerms added right before the try block and a have_cap_chown
> boolean flag being saved for later recall after the pivot instead of the
> (getuid() != 0) check.  That way in the fully-unprivileged case it
> doesn't successfully pivot the now-sanitized build directory only to
> immediately fail to chown it.  Actually, because that chown call doesn't
> result in an exception on failure, it would also work to only add the
> secureFilePerms call.

I went back to v2 + ‘secureFilePerms’ call.

> Also, I've discovered that while mount(2) uses EPERM for both a locked
> mount point and insufficient privileges, umount(2) uses EINVAL for the
> former and EPERM for the latter.  This may be a good way to test that
> we're triggering the mount-locking behavior as intended.

The tests try to MS_REMOUNT the inputs, which is exactly what we want to
prevent; we could test the low-level semantics you describe, but it’s
quite obscure and maybe unnecessary given that we test MS_REMOUNT?

>> The one observable difference compared to current guix-daemon
>> operational mode is that, in the build environment, writing to
>> the root file system results in EROFS instead of EPERM, as you
>> pointed out earlier.  That’s not great but probably acceptable.
>> We’ll only know whether this is a problem in practice once we’ve
>> run the test suites of tens of thousands of packages.
>
> Strictly speaking, it's also observable that the root file system,
> store, /tmp, etc is not owned by uid 0, and that the input store items
> are all mounted read-only.

Right.

I’ll send v4 shortly.  Thanks again for your feedback!

Ludo’.