Subject: Re: bug#36508: GDM files have incorrect owner after temporarily removing service

From: Mark H Weaver <[email-masked]>
Date: Thu, 15 Apr 2021 14:09:17 -0400

Hi Brendan,

Brendan Tildesley <[email-masked]> writes:

> Guix system rollbacks should be a supported feature of Guix, not just a gimmick
> that falls out of its design. It should be that a Guix user could leave their
> system for 5 years, and then do a guix pull; guix system reconfigure in the year
> 2026. Perhaps at that time the new system will break, and then its desirable
> that they can rollback to the previous generation.

This sounds like a good set of goals to strive for.  I'm not sure that
Guix, on its own, will be able to achieve reliable 5-year rollback.  I
think that would require _all_ software in Guix that maintains mutable
state on disk to gracefully support downgrading to a version from 5
years earlier.

Nonetheless, Guix can certainly do its part to try to ensure that
multi-year rollbacks can work, and I agree that it's a good thing to
keep in mind.

> So what fixes we put in to 
> Guix services today need to consider not just how files could have changed in
> the past, but how they might change in breaking ways in the future, within reason.

It's a good thing to keep in mind, yes.

> I don't know off the top of my head of any way that can be done other than to
> have chmod -R gdm:gdm /var/lib/gdm always executed.

I'm not necessarily opposed to doing that, at least as a temporary
workaround for GDM, but I don't think this is a satisfactory solution to
the larger problem.  A few points:

(1) I don't think we can assume that all files owned by a given user
    will be in that user's home directory, especially for "system"
    users.

(2) I also don't think we can assume that all files in a user's home
    directory *should* be owned by that user.  Even if it's true today,
    it might not be true tomorrow.

(3) Groups don't even have home directories.

> On 04/13/2021 10:51 PM Mark H Weaver <[email-masked]> wrote:
>> 
>> There's some discussion of this issue at <https://bugs.gnu.org/44944>,
>> although I'm not sure that Danny's suggested solution is practical.
>> 
>> Here's one idea: when activating a system, *never* delete users or
>> groups if files still exist that are owned by those users/groups.
>> Checking all filesystems would likely be too expensive, but perhaps it
>> would be sufficient to check certain directories such as /var, /etc, and
>> possibly the top directory of /home.
>> 
>> What do you think
>
> Wouldn't that imply that uids could be randomly different on different systems
> with the same configuration, and then remain statically different permanently?

Yes, and I agree that it's suboptimal.

> We want as little randomness and moving parts as possible. It's yet another
> way the system is not actually Functional, but has state.

Agreed.  Danny's suggested solution (UID = hash username) is clearly the
optimal approach in many respects.  It has the nice properties above.

The practical problem I see with Danny's approach is that in order to
make hash collisions sufficiently improbable, our UIDs and GIDs would
need to be much larger than the 16 bits that is widely supported by
POSIX software.  With 16-bit UIDs, the probability of a collision would
be 1.85% with 50 users, and 7.28% with 100 users.

To adopt this approach, I think that our UIDs and GIDs would need to be
at least 31 bits.  These are the problems I see:

(1) It's unlikely that all software in Guix robustly handles such large
    UIDs/GIDs.  Desktop systems with UIDs/GIDs larger than 65533 have
    not been widely tested, as far as I know.

(2) Even with 31 bit IDs, the probability of collisions would still be
    uncomfortably high when large numbers of users are present: with 10k
    users, the probability of hash collisions would be about 2.3%.

(3) We'd need a transition plan for users' existing file systems.

(4) It would be aesthetically unpleasant for our UIDs and GIDs to be
    random-looking numbers with 10 decimal digits.

> Seems this bug spans 3 or so different bug reports. In http://issues.guix.gnu.org/45571
> I commented that Nix uses hard coded id's, sorta like how ports are allocated
> for a purpose:
>
> https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/misc/ids.nix
>
> Perhaps you are thinking of other kinds of security issues that could be caused that
> I'm not thinking of.

I'm not sure what you're getting at here.  The only security issue I've
raised so far is that ownership of files can _effectively_ be changed
when removing services and later adding them back.  For example, in my
case, 'colord' ended up being the owner of files in /var/lib/gdm.

> In that case maybe Nix devs have already made the best choice by
> making them static?

That might well be true.  At the present time, this is the option that
seems most appealing to me.

One possible approach would be to add a field to our 'operating-system'
record that explicitly specifies a total mapping from user/group names
to UIDs/GIDs.  It could either be a procedure (to support Danny's
hashing approach with its nice properties) or possibly also an alist for
convenience.  If any entries were missing, it would raise an error.

One risk to this approach is that users could accidentally make a mess
of their system if they made a mistake while changing that field.

What do you think?

    Thanks,
      Mark