mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Alexey Izbyshev <izbyshev@ispras.ru>
To: musl@lists.openwall.com
Subject: Re: [musl] Calling setxid() in a vfork()-child
Date: Mon, 12 Oct 2020 23:30:58 +0300	[thread overview]
Message-ID: <fcfe55b416f8225de3875699bc126250@ispras.ru> (raw)
In-Reply-To: <20201012145549.GG17637@brightrain.aerifal.cx>

Thank you for the response, Rich!

On 2020-10-12 17:55, Rich Felker wrote:
> Note that in addition to the issue you're asking about, it's
> fundamentally a bad idea to be using set*id() in a vforked child (or
> anywhere in a process that calls vfork) because it leaves moments
> where there are tasks in different privilege domains executing from
> the same VM space. If the task that's dropped privileges does anything
> that could lead to an attacker seizing control of the flow of
> execution, rather than just getting access to the set*id()-reduced
> privilege domain, they have full access to the original privilege
> domain. This is why musl's multithreaded set*id() (__synccall) takes
> care not to admit forward progress of any application code during the
> transition, and goes to the trouble of having a thread list lock that
> unlocks atomically with kernel task exit so that there is no race
> window where a still-live thread can be missed.
> 
Yes, I initially learned about this security issue from your post[1]. I 
proposed to ignore it for the moment in my email because it was hard for 
me to imagine any security implications in a constrained case: if the 
only use of setuid() in a privileged app is to drop privileges in a 
vfork()-child before calling execve(). However, thinking about it more, 
I see that dropping privileges could open the child to new ways of 
interaction from outside of the app in a window before execve(), so, if, 
say, another unprivileged process can ptrace it at the right moment, bad 
things could happen. But now I don't see why wouldn't the same attack be 
applicable to __synccall(). While __synccall() seizes execution of 
application code, I don't see how it could prevent ptrace-like kind of 
an outside attack on a thread at the moment when another thread is in a 
different privilege domain.

> In any case, IMO unless you're programming for NOMMU compatibility,
> you should just forget vfork ever existed. There's no good reason to
> use it. If a process can't fork because it's too big or the fork would
> impact performance too much, posix_spawn can do far more than
> vfork+execve can do portably. It can't do everything you can do with
> vfork+execve if you're willing to break portability rules (i.e. invoke
> UB), but with a helper executable to run in the child you can get that
> all back.
> 
Unfortunately, while posix_spawn() + a helper executable would be fine 
in many cases (more so for applications than libraries), addition of a 
helper to an existing library exposing a process creation API that can't 
be implemented in terms of posix_spawn() may be not straightforward. If 
the helper is just an executable file, we'll need to locate it, which 
may be simply impossible when our library is called if, say, switching 
mount namespaces is involved (which may be out of control of our 
library). Solutions may exist (locate and open() at startup or 
memfd_create(), and then execveat()?), but vfork() (+ preventing 
execution of signal handlers in the child) seems so much simpler, and 
doesn't add the overhead of an extra execve() too.

Alexey

[1] https://ewontfix.com/7

  reply	other threads:[~2020-10-12 20:31 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-12  9:27 Alexey Izbyshev
2020-10-12 14:55 ` Rich Felker
2020-10-12 20:30   ` Alexey Izbyshev [this message]
2020-10-13  2:47     ` Markus Wichmann
2020-10-13  9:52       ` Laurent Bercot
2020-10-13 15:48         ` Alexey Izbyshev
2020-10-13 15:24       ` Alexey Izbyshev
2020-10-13 16:07         ` Rich Felker
2020-10-13 16:52     ` Alexey Izbyshev
2020-10-13 17:05       ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fcfe55b416f8225de3875699bc126250@ispras.ru \
    --to=izbyshev@ispras.ru \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).