On Sun, Jun 28, 2026 at 6:20 AM Christian Brauner <[email protected]> wrote:
>
> On 2026-06-28 14:36:52+02:00, Christian Brauner wrote:
> > > I think the proposed patch will only change behavior if the
> > > interpreter path starts with "$ORIGIN"? That wouldn't work on existing
> > > kernels unless you have a directory literally named "$ORIGIN" in the
> > > cwd, because "$ORIGIN/..." would be interpreted as a normal relative
> > > path.
> >
> > I was thinking:
>
> A few other things came to my mind:
>
> (1) memfds: /memfd:woot-woot
>
>     A memfd doesn't have a path so any $ORIGIN type behavior - script or not -
>     will be at least useless if not very confusing outside of a sandbox.
>
>     Btw, used by runC to guard against binary overwrite attacks.
>
> (1.1) deleted memfds: /memfd:woot-woot (deleted)
>
>       Same as (1).
>
> (2) deleted executables:
>
>     /woot/woot-woot (deleted)
>
> (3) unrecoverable executable paths
>
>     No path can be resolved at all. What to do?
>
> All of that needs consistent, easy to reason about treatment. Reading through
> the glibc implementation of $ORIGIN for shared libraries in rpath - even with
> an eye on cutting through most of the complexity - doesn't give me very warm
> feelings. It feels very hackish and full of edge cases...
>
> Imho, tying the lookup of the interpreter to the binary itself and making the
> kernel responsible for figuring out the relationship by resolving bprm->file
> and splicing it with PT_INTERP is terrible.
>
> So, I kinda like the concept of having relocatable dynamic executables but 
> then
> let's cut through all the userspace red tape and figure out something that's
> super simple and outsources the problem to userspace.
>
> I think the wrap-buddy approach here: https://github.com/Mic92/wrap-buddy is
> going in the right direction in that it gets the kernel completely out of the
> way. I like that a lot more than moving more nasty bits into the kernel 
> itself.
>
> In a way we have been doing something in systemd that goes in a similar
> direction. As of systemd 261 systemd _only_ links against libc and nothing
> else.
>
> Any other shared library is dlopen()ened as needed (discoverable via
> elf-notes). Lennart wrote about this just a few days ago:
> https://mastodon.social/@pid_eins/116781776665322560
>
> This effectively minimizes the work the loader has to do at startup. Imho, 
> your
> effort with wrap-buddy is related. To me moving the loader invocation out of
> the kernel and into userspace makes a lot of sense to me.
>

Wow the systemd approach sounds pretty surprising. As a Nix/NixOS user
having software enable/disable features depending on changes to the
system ad-hoc seems like a footgun. Despite the allure of shared
objects, the are less re-used in practice and rebuilding them when a
CVE appears is just as easy.
A good read to me:
https://web.archive.org/web/20260320072121/https://drewdevault.com/dynlib.html
https://lore.kernel.org/lkml/CAHk-=whs8QZf3YnifdLv57+FhBi5_WeNTG1B-suOES=rcus...@mail.gmail.com/
(yes true, NixOS also uses "shared libraries" but they are effectively
static in how they are setup with fixed paths).

Anyway, I digress.
What other options are there to go after for a relocatable binary? The
steps wrap-buddy has to take... are a bit horrendous in practicality
(although amazing from an engineering-sense).

binfmt itself is configurable and modules can register additional exec
types. What about something similar for ELF & INTERP ?
Maybe we can meet-half way and support it via a plugin architecture
that NixOS can leverage.

Reply via email to