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.

