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 \" ; для остальных применяется только файл LICENSE" );

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

В старых версиях macOS или если отключена подпись kext, загружаемый модуль ядра в пакете расширений ядра может быть загружен пользователями без прав root, если свойство OSBundleAllowUserLoad установлено в значение True в списке свойств пакета. [15] Однако, если какой-либо из файлов в пакете, включая файл исполняемого кода, не принадлежит пользователю root и группе wheel или доступен для записи группе или «другим», попытка загрузить загружаемый модуль ядра завершится неудачей. [16]

Солярис

Модули ядра могут опционально иметь раздел ELF криптографической подписи, который проверяется при загрузке в зависимости от настроек политики Verified Boot. Ядро может обеспечить криптографическую подпись модулей набором доверенных сертификатов; список доверенных сертификатов хранится вне ОС в ILOM на некоторых платформах на базе SPARC. Загрузка модуля ядра, инициированная пользовательским пространством, возможна только из доверенного пути, когда система работает с включенной функцией Immutable Global Zone.

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

Ссылки

  1. ^ «Устаревшие расширения ядра и альтернативы системным расширениям». Apple Inc. Получено 13 марта 2021 г.
  2. ^ "Kernel Extension Programming Topics: Introduction". Apple Inc. 1 сентября 2010 г. Архивировано из оригинала 4 мая 2013 г. Получено 5 мая 2013 г.
  3. ^ "Управление и разработка динамически загружаемых модулей ядра". Hewlett-Packard . 7 июня 2001 г.
  4. ^ «Что определяет, когда загружается драйвер». Microsoft Developer Network . Microsoft . 21 ноября 2012 г. Архивировано из оригинала 6 марта 2013 г. Получено 5 мая 2013 г.
  5. ^ "Руководство по программированию модулей ядра Linux, раздел 2.2 "Компиляция модулей ядра"" . Получено 05.10.2020 .
  6. ^ Линус Торвальдс и др. (21.06.2011). "Documentation/oops-tracing.txt". kernel.org. Архивировано из оригинала 02.10.2011 . Получено 03.10.2011 .
  7. ^ "Испорченные ядра". Руководство пользователя и администратора ядра Linux .
  8. ^ Джонатан Корбет (2006-03-24). "Tainting from user space". LWN.net . Архивировано из оригинала 2011-11-16 . Получено 2011-10-03 .
  9. ^ "Документация поддержки Novell: испорченное ядро". 2007-07-26 . Получено 2011-10-03 .
  10. Джонатан Корбет (27 апреля 2004 г.). «Будучи честным с MODULE_LICENSE». LWN.net. Архивировано из оригинала 2 ноября 2012 г. Получено 30 октября 2012 г.
  11. ^ Эксплуатация загружаемых модулей ядра. Архивировано 04.02.2012 на Wayback Machine.
  12. ^ "Sysctl/kernel.txt". Архивировано из оригинала 15 апреля 2013 г. Получено 4 января 2013 г.
  13. ^ Кис Кук (28.11.2012). "Отключение чистого модуля". outflux.net . Получено 05.10.2020 .
  14. ^ "Kernel Extensions". Mac Developer Library . Apple. 16 сентября 2015 г. Архивировано из оригинала 17 августа 2016 г. Получено 29 сентября 2016 г.
  15. ^ "Info.plist Properties for Kernel Extensions". Apple Inc. Архивировано из оригинала 26 сентября 2012 г. Получено 27 сентября 2012 г.
  16. ^ kextload(8)  –  Руководство системного администратора Darwin и macOS