mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] Consider making issetugid compatible with Linux capabilities
@ 2021-05-02 15:40 Felix Kyros Ang
  2021-05-02 19:53 ` Rich Felker
  0 siblings, 1 reply; 2+ messages in thread
From: Felix Kyros Ang @ 2021-05-02 15:40 UTC (permalink / raw)
  To: musl

Hello,

Musl implements the BSDs' issetugid syscall as a libc function (which
is awesome). Currently, musl's issetugid indicates that the
environment is tainted when it detects additional Linux capabilities
on the executable (set through setcap for example). This causes the
environment to be cleared when the executable is run, leading to some
program breakages. For instance, some libdbus functions use the
environment to identify the dbus session bus ID, and those programs
(linked to libdbus) will fail if Linux capabilities are added to it.

I wonder if it would be possible to tweak musl such that it does not
consider Linux capabilities a tainted privilege. Alternatively, it
could consider only the "highly overloaded" capabilities (such as
CAP_SYS_ADMIN) as tainted privileges. Here are my thoughts on why this
could be a good idea:

- The main purpose of capabilities is to add granular access control
mechanisms for sys administration in Linux, as opposed to the
"traditional" Unix black-and-white superuser model. The attack surface
is reduced, because programs may be granted only the elevated
permissions that they need to perform their function, as opposed to
the "full/complete" set of superuser privileges.

- By treating capabilities as equivalent to superuser privileges,
programs are forced to take up root privileges (e.g. they need to be
run as root or with sudo) in order to perform their intended
operations. This seems to defeat the purpose of adding granular
role-based access control mechanisms through capabilities in the first
place, and has the unfortunate consequence of re-opening the attack
surface again.

Some comparisons with the BSDs' behaviours seem to also support such a change:
- FreeBSD's issetugid checks if setuid and setgid bits are set, and if
the process's owner has been changed since program invocation which
could suggest a potential attempt at privilege escalation. Role-based
access controls are managed through the MAC mechanism, and this
appears to be compatible with issetugid (please correct me if I'm
wrong).

- OpenBSD keeps the old superuser model (making it important to be as
conservative as possible when calling issetugid). However, OpenBSD
uses pledge and unveil to *remove* privileges from superuser programs
(as opposed to grant additional privileges them on non-root
executables) to achieve the same effect.

issetugid seems to be particularly focused on process ownership
changes since program invocation (particular ownership changes from
lower to unqualified superuser privs - from user to root) as happens
with a setuid binary. It seems reasonable to consider a binary that
already has a Linux capability set to be invoking only that limited
subset of known privileges, and not be performing the equivalent of
taking on an "unknowable euid". If so, musl could explicitly decide
which capabilities it does or does not trust (like cap_sys_admin) when
returning whether the process is attempting to run as root or not.

Looking at the code, it looks like musl's issetugid function returns
the libc.secure value when called, and I couldn't find where
libc.secure's value is initialised. If someone could point me in the
right direction, I'll see if I can maybe send in a patch that proposes
a possible solution.

Thanks for your time. Looking forward to your thoughts.

Cheers,
Felix

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [musl] Consider making issetugid compatible with Linux capabilities
  2021-05-02 15:40 [musl] Consider making issetugid compatible with Linux capabilities Felix Kyros Ang
@ 2021-05-02 19:53 ` Rich Felker
  0 siblings, 0 replies; 2+ messages in thread
From: Rich Felker @ 2021-05-02 19:53 UTC (permalink / raw)
  To: Felix Kyros Ang; +Cc: musl

On Sun, May 02, 2021 at 11:40:19AM -0400, Felix Kyros Ang wrote:
> Hello,
> 
> Musl implements the BSDs' issetugid syscall as a libc function (which
> is awesome). Currently, musl's issetugid indicates that the
> environment is tainted when it detects additional Linux capabilities
> on the executable (set through setcap for example). This causes the
> environment to be cleared when the executable is run, leading to some
> program breakages. For instance, some libdbus functions use the
> environment to identify the dbus session bus ID, and those programs
> (linked to libdbus) will fail if Linux capabilities are added to it.

What program is clearing the environment as a result of this? That's
probably where the problem lies.

> I wonder if it would be possible to tweak musl such that it does not
> consider Linux capabilities a tainted privilege. Alternatively, it
> could consider only the "highly overloaded" capabilities (such as
> CAP_SYS_ADMIN) as tainted privileges. Here are my thoughts on why this
> could be a good idea:

No, considering capabilities as "tainted" is an essential security
property of the interface. Without that, you might as well have just
given the invoking user full unconstrained access to the capability.
At least internally (libc.secure), it's trivial to gain full control
over a process if you can bypass this, e.g. with LD_PRELOAD, malicious
message catalogs that enable format vulnerabilities, etc. When the
application is using issetuid() itself, whether it's possible to gain
full control over execution depends on the application. However, if
it's doing what you describe -- execing children while passing through
the environment that it inherited -- then it's trivial to gain control
by passing LD_PRELOAD libs to those children.

> Looking at the code, it looks like musl's issetugid function returns
> the libc.secure value when called, and I couldn't find where
> libc.secure's value is initialised. If someone could point me in the
> right direction, I'll see if I can maybe send in a patch that proposes
> a possible solution.

It comes from AT_SECURE in the aux vector. See ldso/dynlink.c (dynamic
linked case) and sec/env/__libc_start_main.c

Rich

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-02 19:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-02 15:40 [musl] Consider making issetugid compatible with Linux capabilities Felix Kyros Ang
2021-05-02 19:53 ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).