Тільки так, як modprobe"перемагає" безпеку, завантажуючи новий код у ядро.
З різних причин іноді має сенс мати напівпривілейований код (наприклад, графічні драйвери всередині сервера X), що працює в просторі користувача, а не в потоці ядра.
- Вміти
killце легше, якщо тільки він не замикає HW.
- Запросивши на сторінку запит свого коду / даних з файлів у файловій системі. (Пам'ять ядра не є сторінковим)
- Надаючи йому власний віртуальний адресний простір, де помилки на сервері X можуть просто зірвати X-сервер, не знімаючи ядро.
Це не дуже сприяє безпеці, але є великі переваги надійності та архітектури програмного забезпечення.
Введення графічних драйверів у ядро може зменшити контекстні комутації між клієнтами X та сервером X, як-от лише один користувач-> kernel-> користувач, замість того, щоб отримувати дані в інший процес використання простору використання, але X-сервери історично занадто великі і занадто глючні бажати їх повністю в ядрі.
Так, зловмисний код із цими приватними кодами може захопити ядро, якщо воно захоче, використовуючи /dev/memдля зміни коду ядра.
Наприклад, на x86, запустіть cliінструкцію щодо відключення переривань на цьому ядрі після ioplвиклику системи, щоб встановити рівень привілеїв вводу-виводу на дзвінок 0.
Але навіть x86 iopl"тільки" надає доступ до деяких вказівок : вхід / вихід (і рядкові версії вводу / виходу) та cli / sti. Це не дозволяє використовувати rdmsrабо wrmsrчитати чи записувати "типові регістри моделей" (наприклад, IA32_LSTARяка встановлює адресу точки введення ядра для syscallінструкції x86-64 ), або використовувати lidtдля заміни таблиці дескрипторів переривання (що дозволило б вам повністю прийняти над машиною з існуючого ядра, принаймні на цьому ядрі.)
Ви навіть не можете читати контрольні регістри (як, наприклад, CR3, який містить фізичну адресу сторінки-каталогу верхнього рівня, що атакувальний процес може бути корисним як зміщення /dev/memдля зміни власних таблиць сторінок як альтернативу mmapбільшій кількості) /dev/mem. )
invd(недійсні всі кеші без зворотного запису !! ( використовуйте case = ранній BIOS до налаштування оперативної пам’яті)) - це ще одна забава, яка завжди потребує повного CPL 0 (поточний рівень привілеїв), а не лише IOPL. Навіть wbinvdпривілейований, тому що він такий повільний (і не перериваючий), і він повинен обмітати всі кеші по всіх ядрах. (Див Чи є спосіб , щоб очистити весь кеш процесора , пов'язаний з програмою? І використання інструкції WBINVD )
Помилки, які призводять до переходу на неправильну адресу, що працює з даними, як код, таким чином, не можуть виконати жодну з цих інструкцій випадково на сервері X-простору користувача.
Поточний рівень привілеїв (у захищеному та тривалому режимі) - це низькі 2 біти cs(селектор кодового сегмента) . mov eax, cs/ and eax, 3працює в будь-якому режимі для читання рівня привілеїв.
Щоб записати рівень привілеїв, ви робите a jmp farабо call farвстановлюєте CS:RIP(але запис GDT / LDT для цільового сегмента може обмежувати його на основі старого рівня привілеїв, через що користувальницький простір не може цього зробити, щоб підвищити себе). Або ви використовуєте intабо syscallдля переключення на дзвінок 0 у точці введення ядра.
ioplне дає всіх привілейованих інструкцій, тому вона все ще корисна для того, щоб переконатися, що програма-баггі-простір користувача не випадково запускаєтьсяinvd, перестрибуючи пошкоджений вказівник функції, який вказує на виконувану пам'ять, починаючи з0F 08байтів. Я додав відповідь із деяких причин, що не стосуються безпеки, чому корисно, щоб процеси в просторі користувачів підвищували свої привілеї.