← На главную

Кристиан Браунер предложил eBPF-решение с флагом L в binfmt_misc

21.07.2026 06:29 · hackernews

Разработчик из Nix решил замахнуться на святое — поддержку relocatable binaries в Nix. Для этого он полез в ядро Linux. Первая идея была простой: допилить VFS, чтобы там понимали подстановку $ORIGIN в пути к интерпретатору (PT_INTERP). Он отправил патч, нервничал, ждал, что его пошлют. Но мейнтейнер VFS Кристиан Браунер отреагировал доброжелательно, попросил обоснование и сам предложил альтернативу.

Браунер подумал, что вместо тупой замены строки можно сделать механизм гибче — использовать eBPF. А именно, подключить eBPF-программы к подсистеме binfmt_misc. Это та штука в ядре, которая решает, каким интерпретатором запускать бинарник (например, QEMU для ARM или Wine для .exe). Идея в том, чтобы вместо статического скрипта использовать маленькую безопасную программу, работающую прямо в ядре.

Суть такая: загружается eBPF-программа из двух функций. Первая (nix_match) проверяет, является ли файл ELF-исполняемым. Вторая (nix_load) получает путь к бинарнику, вычисляет, где лежит его интерпретатор (используя $ORIGIN), и говорит ядру: «запускай вот этим». Никаких костылей с фиксированными путями.

Но это решило не все проблемы. У binfmt_misc есть фатальный недостаток: когда он передаёт управление интерпретатору, тот становится главным процессом. Он перехватывает argv[0], proc/self/exe и всё такое. Бинарник, который вы хотели запустить, превращается в простой аргумент. Для эмуляторов типа QEMU это нормально, но для простого ld.so — нет. Программы, которые ищут себя через /proc/self/exe, находят динамический линковщик. Кошмар.

Браунер отправил ещё один большой патч, который добавил два новых режима диспетчеризации. Главный для Nix — флаг L (loader substitution). Он работает честно: ядро выполняет целевой бинарник как основной образ, а указанный в правилах интерпретатор просто подменяет PT_INTERP. Никакой подмены процесса, никакой потери идентичности. Обычный ld.so работает без изменений.

Пока патчи лежат в очереди на попадание в ветку -next ядра. Как только релиз выйдет, автор планирует сделать модуль для NixOS, который будет регистрировать такой eBPF-обработчик при загрузке. Но включать его планируют не для всех ELF-файлов подряд, а только для тех, у кого будет новый сегмент PT_INTERP_NIX. Это гарантирует обратную совместимость: старые бинарники работают как обычно, а новые получают возможность стать relocatable.

Читать оригинал →