Загружаемый модуль ядра
В вычислительной технике загружаемый модуль ядра ( LKM ) представляет собой объектный файл , который содержит код для расширения работающего ядра , или так называемого базового ядра , операционной системы . LKM обычно используются для добавления поддержки нового оборудования (в качестве драйверов устройств ) и/или файловых систем или для добавления системных вызовов . Когда функциональность, предоставляемая LKM, больше не требуется, ее можно выгрузить, чтобы освободить память и другие ресурсы.
Большинство современных Unix-подобных систем и Microsoft Windows поддерживают загружаемые модули ядра под разными именами, например, загружаемый модуль ядра ( kld ) во FreeBSD , расширение ядра ( kext ) в macOS (хотя поддержка сторонних модулей прекращается). [1] ), [2] модуль расширения ядра в AIX , динамически загружаемый модуль ядра в HP-UX , [3] драйвер режима ядра в Windows NT [4] и загружаемый модуль ядра ( DKM ) в VxWorks . Они также известны как загружаемые модули ядра (или KLM ) и просто модули ядра ( KMOD ).
Преимущества [ править ]
Без загружаемых модулей ядра операционная система должна была бы включать в себя все возможные ожидаемые функции, скомпилированные непосредственно в базовое ядро. Большая часть этих функций будет находиться в памяти и не использоваться, что приведет к потере памяти. [ нужна ссылка ] , и потребует, чтобы пользователи пересобирали и перезагружали базовое ядро каждый раз, когда им требуются новые функции.
Недостатки [ править ]
Одним из незначительных замечаний по поводу предпочтения модульного ядра статическому ядру является так называемый за фрагментацию штраф . Базовое ядро всегда распаковывается в реальную непрерывную память с помощью процедур установки; таким образом, базовый код ядра никогда не фрагментируется. Когда система находится в состоянии, в котором можно вставлять модули, например, после того, как файловые системы были смонтированы , содержащие модули, вполне вероятно, что любая новая вставка кода ядра приведет к фрагментации ядра, что приведет к незначительному снижению производительности. за счет использования большего количества записей TLB , что приводит к большему количеству промахов TLB. [ нужна ссылка ]
Реализации в разных операционных системах [ править ]
Линукс [ править ]
Загружаемые модули ядра в Linux загружаются (и выгружаются) modprobe
команда. Они расположены в /lib/modules
или /usr/lib/modules
и получили расширение .ko
(«объект ядра»), начиная с версии 2.6 (предыдущие версии использовали .o
расширение). [5] lsmod
Команда выводит список загруженных модулей ядра. В экстренных случаях, когда система не загружается, например, из-за сломанных модулей, определенные модули можно включить или отключить, изменив список параметров загрузки ядра (например, при использовании GRUB , нажав «e» в меню запуска GRUB, а затем редактирование строки параметров ядра).
Проблемы с лицензией [ править ]
По мнению сопровождающих Linux, LKM являются производными от ядра. [ нужна ссылка ] . Сопровождающие Linux терпят распространение проприетарных модулей. [ нужна ссылка ] но позволяет помечать символы как доступные только для модулей GNU General Public License (GPL).
При загрузке проприетарного или несовместимого с GPL модуля будет установлен флаг «загрязнения». [6] [7] в работающем ядре — это означает, что любые возникшие проблемы или ошибки с меньшей вероятностью будут расследованы сопровождающими. [8] [9] LKM фактически становятся частью работающего ядра, поэтому могут повредить структуры данных ядра и вызвать ошибки, которые невозможно будет исследовать, если модуль действительно является проприетарным.
Споры о Linuxant [ править ]
В 2004 году Linuxant, консалтинговая компания, выпускающая проприетарные драйверы устройств в виде загружаемых модулей ядра, попыталась злоупотребить нулевым терминатором в своих MODULE_LICENSE
, как показано в следующем фрагменте кода:
MODULE_LICENSE("GPL\0for files in the \"GPL\" directory; for others, only LICENSE file applies");
Код сравнения строк, используемый ядром в то время, пытался определить, находится ли модуль под лицензией GPL, и остановился, когда он достиг нулевого символа ( \0
), поэтому он был введен в заблуждение, думая, что модуль объявляет свою лицензию просто «GPL». [10]
FreeBSD [ править ]
Модули ядра FreeBSD хранятся в /boot/kernel/
для модулей, распространяемых вместе с операционной системой , или обычно /boot/modules/
для модулей, установленных из портов FreeBSD или пакетов FreeBSD , а также для проприетарных или других двоичных модулей. Модули ядра FreeBSD обычно имеют расширение .ko
. После загрузки машины их можно загрузить с помощью kldload
команда, выгруженная с kldunload
и указан с kldstat
. Модули также можно загружать из загрузчика до запуска ядра либо автоматически (через /boot/loader.conf
) или вручную.
macOS [ править ]
Некоторые загружаемые модули ядра в macOS могут загружаться автоматически. Загружаемые модули ядра также можно загрузить с помощью kextload
команда. Их можно перечислить по kextstat
команда. Загружаемые модули ядра располагаются в связках с расширением .kext
. Модули, поставляемые с операционной системой, хранятся в /System/Library/Extensions
каталог; модули, поставляемые третьими лицами, находятся в других каталогах.
NetWare [ править ]
Модуль ядра NetWare называется загружаемым модулем NetWare (NLM). NLM вставляются в ядро NetWare с помощью команды LOAD и удаляются с помощью команды UNLOAD; тот modules
Команда выводит список загруженных в данный момент модулей ядра. NLM могут находиться в любом допустимом пути поиска, назначенном на сервере NetWare, и они имеют .NLM
как расширение имени файла.
VxWorks [ править ]
Можно создать проект типа загружаемого модуля ядра (DKM) для создания файла «.out», который затем можно загрузить в пространство ядра с помощью команды «ld». Этот загружаемый модуль ядра можно выгрузить с помощью команды «unld».
Солярис [ править ]
Solaris имеет настраиваемый путь загрузки модулей ядра, который по умолчанию равен /platform/platform-name/kernel /kernel /usr/kernel
. Большинство модулей ядра находятся в подкаталогах /kernel
; те, которые не считаются необходимыми для загрузки системы до момента запуска init, часто (но не всегда) встречаются в /usr/kernel
. При запуске сборки ядра DEBUG система активно пытается выгрузить модули.
Бинарная совместимость [ править ]
Linux не предоставляет стабильного API или ABI для модулей ядра. Это означает, что между разными версиями ядра существуют различия во внутренней структуре и функциях, что может вызвать проблемы совместимости. В попытке решить эти проблемы данные о версиях символов помещаются в .modinfo
раздел загружаемых модулей ELF . Эту информацию о версии можно сравнить с информацией о работающем ядре перед загрузкой модуля; если версии несовместимы, модуль не будет загружен.
Другие операционные системы, такие как Solaris , FreeBSD , macOS и Windows ядра , поддерживают API и ABI относительно стабильными, что позволяет избежать этой проблемы. Например, модули ядра FreeBSD , скомпилированные с версией ядра 6.0, будут работать без перекомпиляции с любой другой версией FreeBSD 6.x, например 6.4. Однако они несовместимы с другими основными версиями и должны быть перекомпилированы для использования с FreeBSD 7.x, поскольку совместимость API и ABI поддерживается только внутри ветки.
Безопасность [ править ]
Хотя загружаемые модули ядра являются удобным методом модификации работающего ядра, злоумышленники могут злоупотреблять им в скомпрометированной системе, чтобы предотвратить обнаружение своих процессов или файлов , что позволяет им сохранять контроль над системой. Многие руткиты используют LKM таким образом. не помогают повысить привилегии Обратите внимание, что в большинстве операционных систем модули никак , поскольку для загрузки LKM требуются повышенные привилегии; они просто облегчают злоумышленнику скрытие взлома. [11]
Линукс [ править ]
Linux позволяет отключить загрузку модулей через sysctl опцию /proc/sys/kernel/modules_disabled
. [12] [13] Система initramfs может загружать определенные модули, необходимые для машины при загрузке, а затем отключать загрузку модулей. Это делает безопасность очень похожей на монолитное ядро. Если злоумышленник может изменить initramfs, он может изменить двоичный файл ядра.
macOS [ править ]
В OS X Yosemite и более поздних версиях расширение ядра должно быть подписано кодом сертификата разработчика, который имеет определенное «право». Такой сертификат разработчика предоставляется Apple только по запросу и не выдается автоматически участникам Apple Developer . Эта функция, называемая «подписью kext», включена по умолчанию и дает указание ядру прекратить загрузку, если присутствуют неподписанные расширения ядра. [14] В OS X El Capitan и более поздних выпусках он является частью защиты целостности системы .
В более старых версиях macOS или если подпись kext отключена, загружаемый модуль ядра в пакете расширения ядра может быть загружен пользователями без полномочий root, если для свойства OSBundleAllowUserLoad в списке свойств пакета установлено значение True. [15] Однако, если какой-либо из файлов в пакете, включая файл исполняемого кода, не принадлежит пользователю root и группе Wheel или доступен для записи группе или «другому», попытка загрузить загружаемый модуль ядра завершится неудачей. [16]
Солярис [ править ]
Модули ядра могут дополнительно иметь раздел ELF криптографической подписи, который проверяется при загрузке в зависимости от настроек политики проверенной загрузки. Ядро может обеспечить криптографическую подпись модулей набором доверенных сертификатов; список доверенных сертификатов хранится вне ОС в ILOM на некоторых платформах на базе SPARC. Загрузка модуля ядра, инициированная пользовательским пространством, возможна только по доверенному пути, когда система работает с включенной функцией неизменяемой глобальной зоны.
См. также [ править ]
Ссылки [ править ]
- ^ «Устаревшие расширения ядра и альтернативы системным расширениям» . Apple Inc. Проверено 13 марта 2021 г.
- ^ «Темы программирования расширений ядра: Введение» . Apple Inc. , 1 сентября 2010 г. Архивировано из оригинала 4 мая 2013 г. . Проверено 5 мая 2013 г.
- ^ «Управление и разработка динамически загружаемых модулей ядра» . Хьюлетт-Паккард . 7 июня 2001 г.
- ^ «Что определяет момент загрузки драйвера» . Сеть разработчиков Microsoft . Майкрософт . 21 ноября 2012. Архивировано из оригинала 6 марта 2013 года . Проверено 5 мая 2013 г.
- ^ «Руководство по программированию модулей ядра Linux, раздел 2.2 «Компиляция модулей ядра» » . Проверено 5 октября 2020 г.
- ^ Линус Торвальдс; и др. (21 июня 2011 г.). «Документация/oops-tracing.txt» . ядро.org. Архивировано из оригинала 2 октября 2011 г. Проверено 3 октября 2011 г.
- ^ «Испорченные ядра» . Руководство пользователя и администратора ядра Linux .
- ^ Джонатан Корбет (24 марта 2006 г.). «Заражение из пользовательского пространства» . LWN.net . Архивировано из оригинала 16 ноября 2011 г. Проверено 3 октября 2011 г.
- ^ «Документация поддержки Novell: Испорченное ядро» . 26 июля 2007 г. Проверено 3 октября 2011 г.
- ^ Джонатан Корбет (27 апреля 2004 г.). «Будьте честны с MODULE_LICENSE» . LWN.net. Архивировано из оригинала 2 ноября 2012 года . Проверено 30 октября 2012 г.
- ^ Использование загружаемых модулей ядра , заархивировано 4 февраля 2012 г. на Wayback Machine.
- ^ «Sysctl/kernel.txt» . Архивировано из оригинала 15 апреля 2013 года . Проверено 4 января 2013 г.
- ^ Кис Кук (28 ноября 2012 г.). «Отключение чистого модуля» . outflux.net . Проверено 5 октября 2020 г.
- ^ «Расширения ядра» . Библиотека разработчиков Mac . Яблоко. 16 сентября 2015 года. Архивировано из оригинала 17 августа 2016 года . Проверено 29 сентября 2016 г.
- ^ «Свойства Info.plist для расширений ядра» . Apple Inc. Архивировано из оригинала 26 сентября 2012 года . Проверено 27 сентября 2012 г.
- ^ Darwin и macOS системного администратора Руководство –