Завантажуваний модуль ядра
Завантажуваний модуль ядра (loadable kernel module чи LKM) — об'єктний файл, який містить код, що розширює працююче ядро, або так сказати базове ядро, операційної системи. LKM-и використовуються в основному для додавання підтримки нового апаратного забезпечення та/чи файлових систем, чи додавання системних викликів.
Найбільш сучасні Unix-подібні системи та Microsoft Windows підтримують завантажувані модулі ядра, хоча вони можуть використовувати інші назви для цього, такі як kernel loadable module (kld) в FreeBSD, kernel extension (kext) в OS X[1] та kernel-mode driver в Windows NT.[2] Вони також знані як Kernel Loadable Modules (or KLM), або просто як Kernel Modules (KMOD).
Переваги
Операційна система без завантажуваних модулів ядра могла б мати увесь можливо-очікуваний функціонал вже вбудований в базове ядро. Багато цього функціоналу було б даремно завантажено в пам'ять, тому що не використовувалося б, а просто витрачало б пам'ять, та б потребувало, щоб користувачі перезбирали та перевантажували базове ядро кожен раз, коли їм потрібен новий функціонал. Більшість операційних систем підтримуючи завантажувані модулі ядра включають тільки більш затребуваний функціонал.
Недоліки
Один маленький недолік переваги модульного ядра над статичним — так звана проблема фрагментації. Базове ядро завжди незапаковане в реальну суміжну пам'ять за своєю налаштовуючою процедурою, таким чином базовий код ядра є завжди нефрагментованим. Як тільки система в стані коли модулі можуть бути завантажені — наприклад, змонтували файлову систему, що міститься в модулі — це вірогідно, що будь-який новий код ядра спричинить фрагментацію ядра та внесе маленьку деградацію продуктивності.
Реалізації в інших операційних системах
Linux
Завантажувані модулі ядра в Linux — це завантажені (або вивантажені) за допомогою команди modprobe. Вони розміщені в /lib/modules та мають розширення .ko («kernel object») з версії 2.6 (в попередніх версіях використовувалося розширення .o).[3] Команда lsmod показує список завантажених модулів ядра. В аварійних ситуаціях, коли система не може завантажитися через наприклад зіпсуті модулі, спеціальні модулі можуть бути включені або виключені за допомогою зміни завантажуваних параметрів ядра (наприклад якщо використовується GRUB, натискаєте 'e' в стартовому меню GRUB та редагуєте стрічку параметрів ядра).
Ліцензійні спірні питання
На думку Linux розробників, LKM — це похідний твір ядра. Лінукс розробники дозволяють розповсюдження пропріетарних модулів но символи мають бути марковані як такі які є тільки доступними для GNU General Public License (GPL) модулів.
Під чам завантаження пропріетарного або не GPL-сумісного LKM буде ставитися прапорець 'taint'[4] в працюючому ядрі — це значить що будь-яка проблема чи помилка буде досліджена розробниками з менш імовірністю.[5][6] LKM-и оперативно стали частиною працюючого ядра, вони можуть пошкодити структуру даних ядра та принести дефекти в роботі програми, що можуть не бути дослідженими, якщо модуль справді пропріетарний.
Linuxant суперечка
В 2004, Linuxant— консультуюча компанія, що реалізовувала пропріетарні драйвера пристроїв як завантажувані модулі ядра — спробувала зловжити нульовим символом в MODULE_LICENSE
, як видно в наступному уривку коду:
MODULE_LICENSE("GPL\0for files in the \"GPL\" directory; for others, only LICENSE file applies");
Код порівняння стрічок, який використовується ядром для виявлення ліцензій відмінних від GPL, в момент визначення ліцензії, досяг NULL символу(\0), що, в свою чергу, призвело до зупинки процесу перевірки ліцензії, визначивши її як ліцензію «GPL».[7]
FreeBSD
Модулі ядра для FreeBSD , які розповсюджуються з ОС, зберігаються в /boot/kernel/, а в /boot/modules/ зазвичай встановлені з FreeBSD ports or FreeBSD packages, або є пропріетарними. В іншому випадку тільки двійкові модулі. Модулі ядра FreeBSD мають розширення .ko. Як тільки машина готова, вони можуть бути завантажені за допомогою команди kldload, вивантажені - kldunload, та перечислені — kldstat. Модулі можуть також бути завантажені з завантаєувача перед стартом ядра, або автоматично (через /boot/loader.conf) або вручну.
OS X
Деякі завантажувані модулі ядра в OS X можуть бути завантаженими автоматично. Завантажувані модулі ядра можуть також бути завантаженими з допомогою команди kextload, перечислені — kextstat. Вони розміщені в bundle-ів з розширенням .kext. Модулі, які постачаються з операційною системою зберігаються в директорії /System/Library/Extensions; модулі, які постачаються третьою стороною — в різних інших.
NetWare
Модуль ядра NetWare — називають NetWare Loadable Module (NLM). NLM — вставляються в NetWare ядро командою LOAD, та видаляються командою UNLOAD; команда modules показує всі завантажені на даний момент модулі. NLM можуть розміщуватися в будь-якому пошуковому місці, що прив'язані до NetWare сервера, також вони мають .NLM розширення файла.
Двійкова сумісність
Лінукс не забезпечує стабільний API чи ABI для модулів ядра. Це означає що є різниця у внутрішній структурі та функції між різними версіями ядра, які можуть спричиняти проблеми сумісності. Спробою побороти ці проблеми стало розміщення мітки даних про версію в .modinfo секцію ELF модулів. Ця інформація про версію може бути порівняна з тією, яку має працююче ядро перед завантаженням модуля; Якщо версії несумісні — модуль не буде завантажений.
Інші операційні системи, такі як Solaris, FreeBSD, OS X, та Windows підтримують API та ABI ядра відносно стабільними, що дозволяє уникнути таких проблем. Для прикладу, модулі ядра FreeBSD, які скомпільовані для версії ядра 6.0 будуть працювати без компіляції на будь-якій іншій версії FreeBSD 6.x, наприклад 6.4. Однак вони несумісні з іншими мажорними версіями та повинні бути перезібрані для використання з FreeBSD 7.x, так як API і ABI сумісність підтримується тільки в межах гілки.
Безпека
Так як завантажувані модулі ядра — зручний спосіб зміни працюючого ядра, це може використовуватись нападниками для своїх цілей на скопроментованій системі. Наприклад, щоб уникнути виявлення їхніх процесів та файлів, що дозволяє таким чином підтримувати контроль над системою. Багато руткітів використовують LKM для цього. Запам'ятайте, що на більшості операційних систем модулі не допомагають підвищити привілеї, оскільки підвищені привілеї потрібні для самого завантаження модуля ядра; вони просто полегшують процес приховування слідів нападника.[8]
Лінукс
Лінукс дозволяє забороняти завантаження модулів через sysctl параметр /proc/sys/kernel/modules_disabled
.[9][10] Система Initrd initramfs може завантажувати специфічні модулі, які потрібні для машини під час завантаження і потім забороняти завантаження модулів. Це робить систему безпеки безпеку дуже схожою до такої, яка властива монолітним ядрам. Якщо атакуючий може змінити initramfs, то він зможе змінити і двійковий код ядра.
OS X
На OS X, завантажуваний модуль ядра в ядровому розширеному bundle може бути завантаженим непривілейованим користувачем, якщо властивість OSBundleAllowUserLoad встановлено в True в в списку властивостей bundle.[11] Однак, якщо будь-який з файлів в bundle, включаючи виконувач код, не приналежний root та групі wheel, чи не записаний групою «інші», спроба завантажити модуль ядра провалиться.[12]
Див. також
Примітки
- ↑ «Kernel Extension Programming Topics: Introduction».
- ↑ «What Determines When a Driver Is Loaded».
- ↑ «The Linux Kernel Module Programming Guide, section 2.2 „Compiling Kernel Modules“».
- ↑ Linus Torvalds; et al. (2011-06-21).
- ↑ Jonathan Corbet (2006-03-24).
- ↑ «Novell support documentation: Tainted kernel». 2007-07-26.
- ↑ Jonathan Corbet (April 27, 2004).
- ↑ Exploiting Loadable Kernel Modules
- ↑ «Sysctl/kernel.txt»[недоступне посилання з квітня 2019].
- ↑ Kees Cook (2012-11-28).
- ↑ «Info.plist Properties for Kernel Extensions».
- ↑ Darwin and Mac OS X System Manager's Manual –
Посилання
- Anatomy of Linux loadable kernel modules, IBM DeveloperWorks, July 16, 2008, archived from the original on July 26, 2008
- Online kext database for OSX / Hackintosh
- Ori Pomerantz, Linux Kernel Module Programming Guide
- Copyright Considerations With LKMs, 2008, archived from the original on June 20, 2008
- «Kernel Extension Programming Topics» document for OS X