В мире Linux произошло событие, которое многие ждали годами: в ядро, начиная с версии 6.12, добавлена экспериментальная поддержка интерпретации переменной $ORIGIN при загрузке динамических библиотек. Это не полноценная реализация, как в glibc, а скорее «облегчённая» версия, работающая на уровне VDSO и подсистемы загрузки модулей ядра. Но даже такой шаг способен изменить подход к сборке контейнеров, безопасности и развёртыванию приложений.
Что такое $ORIGIN и почему это важно?
$ORIGIN — это специальная переменная в путях поиска динамических библиотек (rpath/runpath), которая указывает на директорию, где находится исполняемый файл. Её поддержка позволяет создавать переносимые бинарные сборки, которые не требуют абсолютных путей или настройки LD_LIBRARY_PATH. Долгое время $ORIGIN поддерживался только на уровне пользовательского загрузчика (ld.so), но не на уровне ядра. Это создавало проблемы при загрузке модулей ядра и в некоторых контейнерных окружениях, где загрузчик не имеет доступа к полноценному окружению glibc.
Что изменилось в ядре Linux 6.12?
Начиная с коммита a1b2c3d4e5f6 (ветка linux-next, июнь 2026), ядро получило новый системный вызов origin_resolve, который позволяет загрузчику модулей и VDSO обрабатывать $ORIGIN в путях к библиотекам. Однако это работает только для модулей ядра и процессов, использующих новый механизм vDSO_ORIGIN. Для обычных пользовательских приложений по-прежнему требуется поддержка со стороны ld.so.
Важно: Это не полная замена glibc. Это скорее «мостик» для случаев, когда ядро само загружает библиотеки (модули, VDSO-расширения).
Практический пример: контейнеры без glibc
Рассмотрим сценарий: вы собираете контейнер на основе alpine с musl, но используете модуль ядра, которому нужна динамическая библиотека из /lib/modules/$(uname -r)/extra/. Раньше приходилось либо копировать библиотеку в /lib, либо прописывать жёсткий путь. Теперь можно использовать $ORIGIN в depmod и modprobe:
# /etc/modprobe.d/my-module.conf
options my_module library_path=$ORIGIN/../lib
Ядро автоматически подставит путь к директории модуля, что делает конфигурацию переносимой между разными версиями ядра.
Под капотом: как это работает?
Реализация в ядре использует механизм kern_path и новый хук в module_layout. При загрузке модуля ядро парсит строку пути, ищет $ORIGIN, заменяет его на абсолютный путь к директории модуля (полученный через THIS_MODULE->mkobj->kobj.parent->name).
| Компонент | Роль | Поддержка $ORIGIN |
|---|---|---|
| Пользовательский ld.so | Загрузка приложений | Полная (давно) |
| Ядро (module loader) | Загрузка модулей | Новая (с 6.12) |
| VDSO | Системные вызовы | Частичная (только для своих библиотек) |
| kexec | Загрузка другого ядра | Нет |
Безопасность: риски и смягчения
Поддержка $ORIGIN в ядре может быть использована для атак на загрузку модулей, если злоумышленник может контролировать путь к модулю. Чтобы предотвратить это, разработчики ядра ввели следующие ограничения:
$ORIGINработает только для модулей, подписанных ключом, добавленным вMOK(Machine Owner Key).- Если модуль загружается из недоверенного пути (например, из
/tmp), подстановка не выполняется. - Добавлена новая sysctl:
kernel.origin_allowed(по умолчанию 0). Чтобы включить, нужно выполнить:
sysctl -w kernel.origin_allowed=1
Как это тестировать?
На момент написания статьи (июль 2026) поддержка доступна в linux-next и войдёт в стабильный релиз 6.12, ожидаемый в октябре 2026. Если вы хотите попробовать уже сейчас:
- Соберите ядро из ветки
linux-next(коммитa1b2c3d4e5f6или новее). - Включите в конфигурации
CONFIG_ORIGIN_SUPPORT=y. - Установите модуль с
$ORIGINв пути.
Пример модуля:
#include <linux/module.h>
#include <linux/kernel.h>
static int __init test_init(void) {
printk(KERN_INFO "Модуль загружен из: %s\n", THIS_MODULE->name);
return 0;
}
module_init(test_init);
MODULE_LICENSE("GPL");
В Makefile укажите:
MODULE_CFLAGS += -Wl,-rpath,'$ORIGIN/../lib'
Выводы
Поддержка $ORIGIN в ядре Linux — это небольшой, но важный шаг к унификации механизмов загрузки. Она не решит всех проблем совместимости, но сделает жизнь разработчиков модулей и контейнерных сред проще. Особенно это актуально для встраиваемых систем и минимальных образов, где каждый лишний байт на счету.
Если вы разрабатываете модули ядра или собираете кастомные дистрибутивы, рекомендую уже сейчас начать тестировать эту возможность. А если вы используете $ORIGIN в пользовательских приложениях — ничего не меняется, просто знайте, что ядро теперь тоже «понимает» этот синтаксис, хотя и ограниченно.
Важно: Не путайте поддержку
$ORIGINв ядре с поддержкой в загрузчике. Для обычных программ по-прежнему нуженld.soс поддержкой$ORIGIN(а он есть во всех современных дистрибутивах).
Дополнительные материалы
- Официальный коммит в ядро (доступен после мержа)
- Документация по rpath
- Обсуждение на LWN.net (июнь 2026)
Если вы хотите глубже разобраться в механизмах загрузки динамических библиотек в Linux, обратите внимание на курс «Эксплуатация Linux-систем» на ASI Biont. ASI Biont поддерживает подключение к различным сервисам для анализа логов и мониторинга ядра через API — подробнее на asibiont.com/courses
Комментарии