Только так же, как modprobe«побеждает» безопасность, загружая новый код в ядро.
По разным причинам иногда имеет смысл иметь полу-привилегированный код (например, графические драйверы внутри X-сервера), работающий в пользовательском пространстве, а не в потоке ядра.
- Быть способным к
killэтому легче, если это не запирает HW.
- Наличие этого по требованию страницы его код / данные из файлов в файловой системе. (Ядро памяти не является страничным)
- Предоставляя ему свое собственное виртуальное адресное пространство, где ошибки в X-сервере могут просто привести к сбою X-сервера, не разрушая ядро.
Это мало что делает для безопасности, но имеет большие преимущества в надежности и архитектуре программного обеспечения.
Внедрение графических драйверов в ядро может уменьшить переключение контекста между X-клиентами и X-сервером, например, всего лишь на один пользователь-> ядро-> пользователь, вместо того, чтобы загружать данные в другой процесс пространства использования, но исторически X-серверы слишком велики и слишком глючны. хотеть их полностью в ядре.
Да, вредоносный код с этими привилегиями мог бы захватить ядро, если бы захотел, используя /dev/memдля модификации кода ядра.
Или на x86, например, запустите cliинструкцию для отключения прерываний на этом ядре после выполнения ioplсистемного вызова, чтобы установить уровень привилегий ввода-вывода в 0.
Но даже x86 iopl"only" предоставляет доступ к некоторым инструкциям : in / out (и строковые версии in / outs) и cli / sti. Он не позволяет вам использовать rdmsrили wrmsrдля чтения или записи «регистров, специфичных для модели» (например, IA32_LSTARкоторые задают адрес точки входа ядра для syscallинструкции x86-64 ), или lidtдля замены таблицы дескрипторов прерываний (что позволит вам полностью принять на машине из существующего ядра, по крайней мере, на этом ядре.)
Вы даже не можете читать управляющие регистры (например, CR3, который содержит физический адрес каталога страниц верхнего уровня, который атакующий процесс может счесть полезным в качестве смещения /dev/memдля изменения своих собственных таблиц страниц в качестве альтернативы mmapбольшему количеству /dev/mem. )
invd(аннулируйте все кеши без обратной записи !! ( используйте вариант = ранний BIOS до того, как сконфигурирована RAM)) - еще один забавный, который всегда требует полного 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байтов. Я добавил ответ с некоторыми причинами, не связанными с безопасностью, почему полезно, чтобы процессы в пользовательском пространстве повышали свои привилегии.