Technology

Linux kernel to support Nix-style relocatable binaries via eBPF

A new Linux kernel patch series uses eBPF to let Nix and Bazel run binaries from any path, solving a long-standing limitation with a programmable interpreter.

The Linux kernel is set to gain support for relocatable binaries via a proposed eBPF extension to the binfmt_misc subsystem. This will allow programs like Nix to dynamically select a binary's interpreter based on its location, solving a long-standing portability issue. The solution preserves process identity and is expected to be adopted through an opt-in ELF segment in future kernel releases.

A proposed patch series for the Linux kernel promises to solve a long-standing limitation for reproducible build systems like Nix and Bazel: the inability to run relocatable binaries without cumbersome wrapper scripts or patching tools. The solution, which uses eBPF to dynamically select a binary's interpreter, emerged from a collaborative effort on the Linux kernel mailing list and is expected to land in the -next branch soon [citation:6][citation:8].

The $ORIGIN challenge in Linux

The core issue lies in how the Linux kernel handles the PT_INTERP segment of an ELF binary. This segment hardcodes the absolute path to the dynamic linker (e.g., /lib64/ld-linux-x86-64.so.2) that the kernel must load to run the program. For package managers like Nix, which store binaries in content-addressed paths that can vary between systems, this creates a significant problem. A binary built on one machine might have a hardcoded path to a loader that doesn't exist on another, causing the execution to fail [citation:8][citation:12].

While the dynamic linker itself supports the $ORIGIN variable to resolve paths relative to the binary's location, the kernel does not expand this variable in PT_INTERP. This forces projects to rely on post-build tools like patchelf to rewrite the interpreter path or to use wrapper scripts that set up the environment before execution [citation:1].

A programmable solution with eBPF

Developer Farid Zakaria initially proposed adding $ORIGIN support directly to the kernel's Virtual File System (VFS). However, Linux VFS maintainer Christian Brauner pushed back on this idea, citing security concerns and potential for loader injection attacks [citation:1]. Instead, Brauner proposed a more flexible and secure alternative: using eBPF (Extended Berkeley Packet Filter) to programmatically select the interpreter via the existing binfmt_misc subsystem [citation:6].

binfmt_misc is a kernel feature that allows administrators to register handlers for arbitrary binary formats, traditionally using fixed magic bytes and interpreter strings. The new patch series, championed by Brauner and now being carried forward by Zakaria, introduces a new handler type ('B') that allows an eBPF program to be registered as the matcher and loader [citation:1][citation:3].

The proposed eBPF program can inspect the binary's header, its full path, or even new ELF segments to determine the correct interpreter on a per-binary basis. A sample program provided in the patch series demonstrates how to read a binary's file path using the bpf_path_d_path() helper and construct a loader path relative to it, effectively supporting the $ORIGIN behavior in the kernel for the first time [citation:8].

Preserving process identity

A critical enhancement in the patch series addresses a side-effect of the traditional binfmt_misc mechanism. Normally, the registered interpreter takes over the process identity, and the original binary becomes its argument. This means tools that rely on /proc/self/exe to find their own location will instead point to the interpreter, which breaks many applications [citation:12].

To solve this, the series introduces new dispatch modes, most notably the 'L' flag for loader substitution. With this flag, the kernel executes the matched binary as the main image and substitutes the chosen eBPF-selected interpreter for the loader in PT_INTERP, preserving the process's identity and making the hand-off transparent [citation:6][citation:12].

What's next for Nix and Linux

The patch series is currently a work-in-progress, but it is being developed on the kernel mailing list and is on track for the -next branch. The plan is to gate this functionality behind a new PT_INTERP_NIX segment, ensuring that the eBPF handler only acts on binaries that explicitly opt-in, leaving standard binaries unaffected [citation:6].

Once the patches land in a stable kernel release, developers plan to upstream a NixOS module to register the eBPF handler automatically at boot. This will allow developers using Nix to produce truly relocatable binaries without patching or wrapper scripts, significantly improving portability and simplifying the build process [citation:12][citation:6].