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
next prev parent 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).