Subject: Re: [bug#61462] Add support for file capabilities(7)

From: Vagrant Cascadian <[email-masked]>
Date: Thu, 23 Mar 2023 21:31:53 -0700

On 2023-03-04, Ludovic Courtès wrote:
> Tobias Geerinckx-Rice <[email-masked]> skribis:
>
>> I need to offload some of my eternally rebased local patches. Here's
>> one that makes it easy to assign capabilities(7) — currently through
>> setcap(8) — to programmes like we can set{u,g}id.
>>
>> There are many packages that benefit from this.  Mine are:
>>
>>  (privileged-programs
>>    (cons* (privileged-program
>>            (file-append mtr "/sbin/mtr")
>>            (capabilities "cap_net_raw+ep"))
>>           (privileged-program
>>            (file-append nethogs "/sbin/nethogs")
>>            (capabilities "cap_net_admin,cap_new_raw+ep"))
>>           (privileged-program
>>            (file-append light "/bin/light")
>>            (setuid? #t))
>>           %default-privileged-programs))
>
> Neat!

Agreed! Thanks!

>> I'm quite opinionated about the setuid-programs unification: there
>> should not be multiple confusing and masking layers of privilege, and
>> it should be possible to setgid a capable executable.
>
> So you mean that ‘privileged-programs’ should entirely replace
> ‘setuid-programs’, right?
>
> I’m a bit unsure about using file capabilities:
>
>   1. File capabilities are persistent and less visible than setuid bits
>      (you won’t see them with “ls -l”), so easily overlooked.  Could
>      there be a risk of lingering file capabilities when reconfiguring a
>      system?

Does reconfigure leave old setuid binaries laying around in
/run/setuid-programs currently? That sounds like leaking state from
previous generations into the current generation, and should be fixed if
it is indeed the case.

Seems like with setuid/setgid and the proposed priviledged binaries, the
setuid/setgid bits and capabilties should be explicitly set on any
defined binaries, and any that are left over in the /run/*-programs
directories should be... forcibly removed! Otherwise your current system
is vulnerable to previous potentially bad choices indefinitely...

Basically, guix system reconfigure should be fastidious and ideally
deterministic with generating and updating /run/*-programs ...

>   2. How ’bout portability to different file systems and to GNU/Hurd?

Currently I *think* /run/setuid-programs is tmpfs (at least on systems I
have used running a linux-libre kernel) ... I do not think this attempts
to change that...; we probably do not need broad filesystem
compatibility, just whatever filesystem /run/*-programs is implemented
on.

And since they are not compatibly with GNU/Hurd, then let us drop
support for x86_64-linux, riscv64-linux, ppc64el-linux, arm64-linux,
etc. ... to make sure things are compatible! :P

In all seriousness though, while I appreciate thinking about broad
compatibility across different types of systems, I am a bit nervous
about an approach that would require features to behave compatibly
across all systems...

...though I suspect you were more getting at "What are the consequences
of implementing this for some other system types?"

>   3. What’s the complexity/benefit ratio?  :-)
>
> Then there’s the compatibility story with moving from
> /run/setuid-programs to /run/privileged-programs etc. that’ll have to be
> handled with care.

I am less opinionated about adding yet another directory to PATH,
although obivously then you get into the weird issues with old $PATH
values laying around (e.g. not getting the new directory added until
logging out or re-loading the running profile)

> I’m very much sold to the principle of least authority, but I feel like
> POSIX capabilities (not to be confused with “actual” capabilities) are a
> bit of a hack.

And setuid/setgid is not a hack? It seems like essentially the same
thing, just with no granularity...

> Thoughts?

There are some things that are just not possible without capabilities,
and setuid/setgid is a dangerous hammer that should be used very
sparingly, if at all, and capabilities are no *worse* that
setuid/setgid, allowing a finer grained set of problems :)

The need for this functionality has come up more than a few times:

  https://issues.guix.gnu.org/27415
  https://issues.guix.gnu.org/39136
  https://issues.guix.gnu.org/55683

And possibly a few others:

  https://issues.guix.gnu.org/search?query=setcap

live well,
  vagrant