From: "Farid Zakaria" <farid.m.zakaria@gmail.com>
To: "Christian Brauner" <brauner@kernel.org>,
"Alessandro Di Federico" <ale@rev.ng>
Cc: "Farid Zakaria" <farid.m.zakaria@gmail.com>,
<david.laight.linux@gmail.com>, <jack@suse.cz>,
<jannh@google.com>, <kees@kernel.org>,
<linux-fsdevel@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-kselftest@vger.kernel.org>, <linux-mm@kvack.org>,
<mail@johnericson.me>, <shuah@kernel.org>,
<viro@zeniv.linux.org.uk>, "Gemini" <assistant@google.com>
Subject: Re: [RFC PATCH] fs: binfmt_misc: introduce eBPF-based matching and interpreter selection
Date: Sun, 02 Aug 2026 15:54:15 -0700 [thread overview]
Message-ID: <DKETT5RWDAG9.1AP6L1IJ3CL72@gmail.com> (raw)
In-Reply-To: <20260731-batterie-galant-zumachen-d4b91acf8af0@brauner>
On Fri Jul 31, 2026 at 2:41 AM PDT, Christian Brauner wrote:
> On Fri, Jul 31, 2026 at 12:46:04AM +0200, Alessandro Di Federico wrote:
>> One could delegate the feature to user space, but that makes it much
>> harder to get adopted in a uniform way.
>>
>> Will systemd, Android [1] and OpenWrt implement this? In the same way?
>> If so, at that point it could have just been a feature of the Linux ELF
>> extension.
>
> Whether systemd, Android or OpenWrt adopt something isn't a decision the
> kernel gets to make and it isn't one it has to make. Merging code doesn't
> create adoption. It creates an obligation to keep the behavior working
> forever. That includes the machines whose owners never asked for it.
>
> It's also not how ELF conventions get established. PT_GNU_STACK and
> PT_GNU_PROPERTY are the two OS-range headers our loader acts on. And
> they came out of the toolchain and we implemented them afterwards.
>
> The one time we picked a program header type ourselves ahead of the ABI
> PT_ARM_MEMTAG_MTE in 761b9b366cec we collided with PT_AARCH64_UNWIND
> and had to change the name and the value three months later. We got away
> with it because it's a coredump segment that gdb reads, not the exec
> behavior of every binary on the system.
>
> If you want systemd, Android and OpenWrt to agree on one marker, the
> thing that produces that agreement is generic-abi with binutils and
> glibc/musl on board, and then we can implement it.
>
> So we don't actually disagree about there being an ELF feature. We
> disagree about what the header means. My position is that the header
> names the intent and userspace implements the resolution. Yours is that
> the kernel does both.
>
>> Of course the Android people could disable the feature even if it's
>> in the kernel, but if the convention is established by the kernel,
>> there's really no reason to deviate from it in the way it's implemented.
>
> The kernel can't establish this convention. It can only implement one.
> If binutils won't emit the header and no loader cooperates, we've shipped
> uapi that nothing uses and that we still can't remove.
>
>> The whole point of the portability thing is to reduce the assumptions
>> you make about the target system. Ideally, you just want to use
>> features widely available in kernels in the wild.
>
> Sure, but nothing merged today is widely available tomorrow. Both need a
> new kernel. Uniform-by-default doesn't arrive sooner because it went
> into core elf.
>
> And a new phdr doesn't degrade nicely. On any kernel that doesn't know
> it the binary has no PT_INTERP it loads as static. Dies horribly at an
> unrelocated _start.
>
> And keeping a literal $ORIGIN fallback in PT_INTERP instead and old
> kernels or gVisor open it cwd-relative, so an attacker who controls cwd
> plants ./$ORIGIN/ld.so.
>
>> But from what I understand from another thread, your intention is to
>> use userspace as testbench, correct?
>
> Not testbench as in "go away and come back later". The difference is
> where the semantics live once they turn out to be wrong. Get a corner
> case wrong in a bpf handler and the distro ships a fix in the next
> update. Get it wrong in load_elf_binary() and it's the exec behavior of
> arbitrary binaries... which we can't change afterwards.
>
>> > This is policy that the admin should decide
>>
>> Agreed, but the admin is probably satisfied with enabling/disabling,
>> not deciding whether the program header type is `PT_INTERP_WITH_ORIGIN`
>> or `PT_ORIGIN_ENABLED_INTERP`. Same for the distro maintainers.
>
> Nobody is asking an admin to name a program header type. The distro ships
> the handler and a file in /etc/binfmt.d and the admin never sees either.
>
> But note what you argued here... If it needs an enable/disable switch
> then it is policy. And the only question left is what the switch looks
> like. A global boot-time on/off is the worst available version of it.
> It's one bit, machine-wide and can't be scoped to a subtree, can't be
> delegated.
>
>> Then, from a security perspective, AFAIU, implementing this in
>> eBPF does not solve the problems that have been discussed.
>>
>> For instance, `selftests/exec: add binfmt_misc bpf-backed handler test`
>> does string manipulation (no `openat`).
>
> The handler doing nothing but string manipulation isn't a simplification
> in the example. It's the design. The program never opens anything. It
> computes a path and hands it back, and the kernel opens it with
> open_exec() under the credentials of whoever called execve(). There is
> no openat() to add. And fwiw, it also supports pre-opened binaries for
> really crazy use-cases where you want to pin a set of loaders once.
>
> The module RFC resolved $ORIGIN in kernel code opened the interpreter
> itself with file_open_root(..., O_RDONLY, 0).
> That skips everything open_exec() does and it achors path resolution at
> the binary's directory. .. clamps there and absolute symlinks resolve
> inside it. $ORIGIN/../lib/ld.so, which is the RPATH idiom everyone
> actually writes, silently means <bindir>/lib/ld.so.
>
> I'm not holding an RFC to final-code standards. The point is that this
> is fiddly.
>
>> Overall, I feel like the current proposal pushes back on having a new
>> ELF feature for security reasons, but then delegates to distro
>> maintainers who want to use the feature to take those risks.
>
> It doesn't delegate the risk. It binds it to whoever wants the feature.
>
> Whether resolving the loader relative to the binary is safe depends on
> invariants of the deployment. Is the tree immutable, who may write to it,
> which prefixes are trusted. The kernel doesn't know any of that.
> /nix/store is root-owned and immutable, so the policy is safe there. The
> same semantics pointed at a directory the user can write to is a hole.
> Only the deployment can tell those two apart.
>
> Userspace arrived at the same answer, incidentally. glibc expands $ORIGIN
> under __libc_enable_secure only when it is the first path component and
> the result is rooted in a trusted directory. That trusted-directory
> notion is exactly what an in-kernel implementation would have to invent.
> And it is deployment-specific.
>
>> But also, distro maintainers don't really need this feature because
>> they can just write /nix.
>
> Right, and that's the honest core of it. The people who need this are
> users on machines that someone else administers.
>
> But "default-enabled ELF feature" is a strange shape of fix for it.
> Because the machines you'd be enabling it on belong to the people who
> never asked. This proposals is to change what exec does for everyone
> else in order to serve some use-cases.
>
>> I'd be happy to try to work on the example eBPF program using openat,
>> address the various security concerns that have been mentioned until it
>> looks right and then it could be loaded by default, but with an option
>> to disable it. But I'm not sure whether there's such a thing as "default
>> loaded eBPF program".
>
> And there is such a thing. The distro ships the object plus a file in
> /etc/binfmt.d and systemd loads it at boot. That is a default-loaded
> program with an option to disable, it just lives in the distro image
> rather than in vmlinux. If one handler ends up being what everybody
> ships, that's the uniformity you're after, and nobody had to freeze
> resolution semantics to get it. Could even be upstream in systemd.
>
>> Alternatively, I could extend the ELF core as a parallel feature of
>> the eBPF-based mechanism, reviving some patches from previous
>> iterations.
>
> I'd rather not, for the reasons above.
Christian,
Could you help me please understand how the next branch makes
its way to the kernel?
I see NixOS Offers the latest as of 7.1.
The topic for binfmt is named on 7.3.binfmt in vfs so my assumption is
that it's slated for 7.3.
So that means when Linux pulls for 7.3.rc1 I could start to test it on
NixOS? Maybe 3 more weeks?
next prev parent reply other threads:[~2026-08-02 22:54 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-22 4:39 [PATCH 0/2] fs: support $ORIGIN in ELF interpreter paths Farid Zakaria
2026-06-22 4:39 ` [PATCH 1/2] " Farid Zakaria
2026-06-22 9:53 ` Jori Koolstra
2026-06-23 20:14 ` Kees Cook
2026-06-23 20:35 ` Farid Zakaria
2026-06-22 4:39 ` [PATCH 2/2] selftests/exec: add test suites for $ORIGIN interpreter resolution Farid Zakaria
2026-06-22 10:39 ` [PATCH 0/2] fs: support $ORIGIN in ELF interpreter paths Jan Kara
2026-06-22 17:15 ` Farid Zakaria
2026-06-22 21:08 ` John Ericson
2026-06-25 8:50 ` Christian Brauner
2026-06-25 19:34 ` John Ericson
2026-06-26 12:39 ` Jann Horn
2026-06-26 13:26 ` David Laight
2026-06-26 13:34 ` Jann Horn
2026-06-26 16:28 ` David Laight
2026-06-28 12:36 ` Christian Brauner
2026-06-28 13:20 ` Christian Brauner
2026-06-28 18:44 ` David Laight
2026-06-30 16:58 ` Farid Zakaria
2026-07-02 6:47 ` Christian Brauner
2026-06-30 17:59 ` David Laight
2026-07-02 21:42 ` [RFC PATCH] fs: introduce pluggable ELF interpreter loader registry Farid Zakaria
2026-07-03 9:22 ` Christian Brauner
2026-07-03 18:32 ` Farid Zakaria
2026-07-04 8:15 ` Christian Brauner
2026-07-04 21:14 ` [RFC PATCH] fs: binfmt_misc: introduce eBPF-based matching and interpreter selection Farid Zakaria
2026-07-06 16:01 ` Christian Brauner
2026-07-06 16:47 ` Farid Zakaria
2026-07-07 11:34 ` Christian Brauner
2026-07-07 19:45 ` Christian Brauner
2026-07-07 22:44 ` Farid Zakaria
2026-07-08 9:14 ` Christian Brauner
2026-07-08 16:47 ` Christian Brauner
2026-07-09 4:07 ` Farid Zakaria
2026-07-09 8:46 ` Christian Brauner
2026-07-21 23:18 ` Alessandro Di Federico
2026-07-22 13:33 ` Christian Brauner
2026-07-30 22:46 ` Alessandro Di Federico
2026-07-31 9:41 ` Christian Brauner
2026-08-02 22:54 ` Farid Zakaria [this message]
2026-08-05 7:56 ` Christian Brauner
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=DKETT5RWDAG9.1AP6L1IJ3CL72@gmail.com \
--to=farid.m.zakaria@gmail.com \
--cc=ale@rev.ng \
--cc=assistant@google.com \
--cc=brauner@kernel.org \
--cc=david.laight.linux@gmail.com \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=kees@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mail@johnericson.me \
--cc=shuah@kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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