stringtranslate.com

Загружаемый модуль ядра

В вычислительной технике загружаемый модуль ядра ( 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 \0 для файлов в каталоге \" GPL \" ; для остальных применяется только файл ЛИЦЕНЗИИ" );

Код сравнения строк, используемый ядром в то время, пытался определить, находится ли модуль под лицензией 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в качестве имени файла они имеют расширение.

Вксворкс

Можно создать проект типа загружаемого модуля ядра (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. Загрузка модуля ядра, инициированная пользовательским пространством, возможна только по доверенному пути, когда система работает с включенной функцией неизменяемой глобальной зоны.

Смотрите также

Рекомендации

  1. ^ «Устаревшие расширения ядра и альтернативы системным расширениям» . Apple Inc. Проверено 13 марта 2021 г.
  2. ^ «Темы программирования расширений ядра: Введение» . Apple Inc. , 1 сентября 2010 г. Архивировано из оригинала 4 мая 2013 г. . Проверено 5 мая 2013 г.
  3. ^ «Управление и разработка динамически загружаемых модулей ядра». Hewlett Packard . 7 июня 2001 г.
  4. ^ «Что определяет, когда загружен драйвер» . Сеть разработчиков Microsoft . Майкрософт . 21 ноября 2012. Архивировано из оригинала 6 марта 2013 года . Проверено 5 мая 2013 г.
  5. ^ «Руководство по программированию модулей ядра Linux, раздел 2.2 «Компиляция модулей ядра»» . Проверено 5 октября 2020 г.
  6. ^ Линус Торвальдс; и другие. (21 июня 2011 г.). «Документация/oops-tracing.txt». ядро.org. Архивировано из оригинала 2 октября 2011 г. Проверено 3 октября 2011 г.
  7. ^ «Испорченные ядра». Руководство пользователя и администратора ядра Linux .
  8. ^ Джонатан Корбет (24 марта 2006 г.). «Заражение из пользовательского пространства». LWN.net . Архивировано из оригинала 16 ноября 2011 г. Проверено 3 октября 2011 г.
  9. ^ «Документация поддержки Novell: Испорченное ядро» . 26 июля 2007 г. Проверено 3 октября 2011 г.
  10. Джонатан Корбет (27 апреля 2004 г.). «Будь честен с MODULE_LICENSE». LWN.net. Архивировано из оригинала 2 ноября 2012 года . Проверено 30 октября 2012 г.
  11. ^ Использование загружаемых модулей ядра, заархивировано 4 февраля 2012 г. на Wayback Machine.
  12. ^ "Sysctl/kernel.txt". Архивировано из оригинала 15 апреля 2013 года . Проверено 4 января 2013 г.
  13. ^ Кис Кук (28 ноября 2012 г.). «Отключение чистого модуля». outflux.net . Проверено 5 октября 2020 г.
  14. ^ «Расширения ядра». Библиотека разработчиков Mac . Яблоко. 16 сентября 2015 года. Архивировано из оригинала 17 августа 2016 года . Проверено 29 сентября 2016 г.
  15. ^ «Свойства Info.plist для расширений ядра» . Apple Inc. Архивировано из оригинала 26 сентября 2012 года . Проверено 27 сентября 2012 г.
  16. ^ kextload(8)  -  Руководство системного менеджера Darwin и macOS .