Поддержка ядром произвольных двоичных форматов (binfmt_misc)
Благодаря данной особенности ядра вы можете запускать большинство програм просто написав имя исполнимого файла в оболочке. Это могут быть даже программы предназначенные для других ОС или аппаратных платформ.
Для того, чтобы воспользоваться этой возможностью вы должны объяснить подсистеме binfmt_misc какой интерпретатор использовать для запуска конкретных бинарных файлов. Binfmt_misc определяет тип бинарных файлов по совпадению некоторых байт в начале файла с заданной маской - "магической" последовательностью (могут сравниваться отдельные биты). Также binfmt_misc может определять тип файла просто по расширению, например .jar или .exe.
Для начала вам нужно выполнить монтирование binfmt_misc:
#> mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
Теперь для регистрации нового типа бинарных файлов вам достаточно сформировать примерно такую строку :name:type:offset:magic:mask:interpreter:flags и записать её в /proc/sys/fs/binfmt_misc/register. Разберёмся, что означают поля в нашей строке:
-
name
Это идентификатор нашего формата. Новый /proc-файл будет создан с именем /proc/sys/fs/binfmt_misc/name. По вполне очевидным причинам этот идентификатор не может содержать слэшей (/).
-
type
Тип распознавания файла. M (magic) для соответствия по заданному шаблону или E (extension) для определения по расширению файла.
-
offset
Смещение magic/mask от начала файла в байтах. По умолчанию равно 0 и вы можете не указывать его (например :name:type::magic...). Не используется при идентификации типа файла по расширению.
-
magic
Строка с последовательностью байт, по которой binfmt_misc определяет тип файла. Эта строка может содержать байты в шестнадцатиричной кодировке наподобие \x0a или \xA4. Нужно помнить, что все нулевые байты должны быть экранированы, так как разбор строки прекращается на первом нулевом байте. Если выбран тип определения по расширению файла, то строка должна быть равна нужному расширению без точки (.) и не может содержать шестнадцатиричных кодов и слэшей.
-
mask
Опциональная маска для magic (по умолчания все байты равны 0xff). С помощью этой маски вы можете определить только конкретные биты файла для соответствия байтам magic. К последовательности байт из файла применяется операция побитового AND с маской. Не используется при идентификации типа файла по расширению.
-
interpreter
Эта программа будет запущена с бинарным файлом в качестве первого аргумента (содержит полный путь к файлу).
-
flags
Опциональное поле, которое позволяет контролировать некоторые аспекты запуска интерпритатора. Представляет собой набор флагов (строку из заглавных букв), каждый из которых определяет соответствующее поведение. Поддерживаются такие флаги:
- P - preserve-argv[0]
- O - open-binary
- C - credentials
- F - fix binary
Существующие ограничения:
- строка регистрации бинарного формата не может превышать 1920 символов
- magic поле должно находиться в первых 128 байтах файла (offset+size(magic) должно быть меньше 128)
- строка названия интерпретатора не должна превышать 127 символов
Для начала использования binfmt_misc он должен быть предварительно смонтирован в нужное место. Вы можете это сделать с помощью команды
#> mount -t binfmt_misc none /proc/sys/fs/binfmt_miscили путём добавления в /etc/fstab такой строки
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0для автоматического монтирование при загрузке системы.
При добавлении нескольких форматов порядок добавления важен! Последний добавленный проверяется первым!
Несколько примеров использования:
поддержка исполнимых файлов Windows при помощи wine:
#> echo ':DOSWin:M::MZ::/usr/local/bin/wine:' > /proc/sys/fs/binfmt_misc/register
Вы можете активировать или деактивировать обработку определённых форматов файлов простой записью 1 (активировать) или 0 (деактивировать) в соответствующий /proc/sys/fs/binfmt_misc/type_name файл. Тут type_name - идентификатор формата фала. Для примера, приведённого выше, деактивация будет иметь вид:
#> echo '0' > /proc/sys/fs/binfmt_misc/DOSWinа активация, соответственно:
#> echo '1' > /proc/sys/fs/binfmt_misc/DOSWin
Для глобального включения/отключения данной функциональности можно записать 0 или 1 в файл /proc/sys/fs/binfmt_misc/status.