public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "Zack Weinberg" <zack@owlfolio.org>
To: "Florian Weimer" <fweimer@redhat.com>
Cc: <libc-alpha@sourceware.org>
Subject: Re: Maybe we should get rid of ifuncs
Date: Wed, 24 Apr 2024 09:53:33 -0400	[thread overview]
Message-ID: <D0SEJ05NIQK3.13X1P7VVW841R@owlfolio.org> (raw)
In-Reply-To: <87cyqfc3l2.fsf@oldenburg.str.redhat.com>

On Tue Apr 23, 2024 at 2:54 PM EDT, Florian Weimer wrote:
> * Zack Weinberg:
> > The XZ exploit used an ifunc resolver to rewrite a whole bunch of
> > PLT entries, intercepting both calls within sshd proper, and calls
> > from sshd to libcrypto.so (i.e. OpenSSL's general-purpose
> > cryptography library).
>
> GOT rewriting wasn't required.  OpenSSL itself has support for hooking
> the relevant functions:
>
>   <https://openssl.org/docs/man3.0/man3/RSA_set_method.html>
>
> For some of the link orders I've seen, plain ELF symbol interposition
> would have worked as well.  We don't know if such a thing gets detected
> in practice.

I haven't looked closely at the actual Trojan payload myself; I didn't
know it overtly defined symbols that collide with libcrypto entry
points (thus potentially interposing those symbols).

My goal with this proposal is not to make XZ-type exploits
*impossible*, but rather, to make them easier to detect.  Calls to
RSA_set_method, calls to the "newer OSSL_PROVIDER API" as mentioned in
the above manpage, and symbol collisions between libraries that have
no business interposing on each other: these can all be mechanically
detected, at least in principle.

> > Ifuncs were already a problem -- resolvers are arbitrary application
> > code that gets called from deep within the guts of the dynamic loader,
> > possibly while internal locks are held (I don't know for sure).
>
> Internal locks are held.

Yikes! That by itself seems like a strong argument for replacing this
mechanism.

> > In -z now mode, they are called not just before the core C library is
> > fully initialized, but before symbol resolution is complete, meaning
> > that they can't necessarily make *any* function calls; we've had any
> > number of bug reports about this.
>
> We are getting closer to be able to fully initialize libc before IFUNC
> resolvers run.

It's good to know that it's *possible* to make ifunc resolvers more
robust, but right now I'm not sure it's *worthwhile*.  Unless someone
has a use case that isn't CPU-based code selection, I currently think
replacing ifuncs with something declarative would be a good idea
regardless of potential security benefits.

> In the other direction, I think it would be valuable to offer a mode
> where we run ELF constructors when .data.rel.ro is still writable.

What uses do you see for this mode?

> (In general, I'd be worried to chase last month's problem.)

Well, this is hardening -- every little bit helps.  As I said above,
my security goal here is to make it so potential interception of
function calls to library A by library B is easily machine detectable.
We would still need to build the machine, of course, but that's well
within the scope of existing projects (e.g. archive-wide Lintian scans).

> I'm not sure how valuable it is to prevent code execution at the
> relocation stage when a few microseconds later, the ELF constructor is
> invoked, which by definition contains arbitrary code.

I see it as valuable precisely because ELF constructors (should)
run after the PLT and GOT are made read-only.

I do have a sketch of what it would take to move ld.so completely
out of process, if you're interested in bigger hammers.

> It's possible to revert RELRO.  We do that for static dlopen on some
> architectures (something that could be avoided with early libc
> initialization described above).

What would it take to get rid of that possibility?

zw

  reply	other threads:[~2024-04-24 13:53 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-23 18:14 Zack Weinberg
2024-04-23 18:39 ` enh
2024-04-23 19:46   ` Palmer Dabbelt
2024-04-24 13:56   ` Zack Weinberg
2024-04-24 14:25     ` enh
2024-04-23 18:52 ` Sam James
2024-04-23 18:54 ` Florian Weimer
2024-04-24 13:53   ` Zack Weinberg [this message]
2024-04-23 19:26 ` Andreas Schwab
2024-04-24 13:54   ` Zack Weinberg
2024-04-24  1:41 ` Richard Henderson
2024-04-24 14:43   ` Zack Weinberg
2024-04-24 15:09     ` enh
2024-04-28  0:24     ` Peter Bergner
2024-05-02  2:59       ` Michael Meissner
2024-04-30  8:42 ` Simon Josefsson

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=D0SEJ05NIQK3.13X1P7VVW841R@owlfolio.org \
    --to=zack@owlfolio.org \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /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.
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 read-only IMAP folder(s) and NNTP newsgroup(s).