Объясните сообщение коммита Linux, которое исправляет / защищает POP SS с последующим прерыванием #BP (INT3) - PullRequest
0 голосов
/ 11 мая 2018

Это относится к CVE-2018-8897 (что относится к CVE-2018-1087 ), описанному следующим образом:

Заявление в Руководстве по системному программированию Руководства разработчика программного обеспечения для архитектуры Intel 64 и IA-32 (SDM) было неправильно использовано при разработке некоторых или всех ядер операционной системы, что привело к неожиданному поведению исключений #DB, которые откладываются MOV SSили POP SS, о чем свидетельствует (например) повышение привилегий в Windows, macOS, некоторых конфигурациях Xen, FreeBSD или сбой ядра Linux.Инструкции MOV to SS и POP SS запрещают прерывания (включая NMI), точки останова данных и исключения одношагового прерывания до границы инструкции, следующей за следующей инструкцией (SDM Vol. 3A; раздел 6.8.3).(Запрещенные точки останова для данных - это точки памяти, к которым обращается команда MOV - SS или POP - SS.) Обратите внимание, что исключения отладки не блокируются системным флагом разрешения прерывания (EFLAGS.IF) (SDM Vol. 3A; раздел 2.3),Если инструкция, следующая за инструкцией MOV-SS или POP-SS, является инструкцией типа SYSCALL, SYSENTER, INT 3 и т. Д., Которая передает управление операционной системе при CPL <3, исключение отладки доставляется после передачи в CPL <3завершено.Ядра ОС могут не ожидать такого порядка событий и, следовательно, могут столкнуться с непредвиденным поведением при их возникновении. </p>

При чтении этого связанного git commit с ядром Linux , я заметил, что коммитсостояния сообщения:

x86 / entry / 64: не использовать запись IST для стека #BP

В # BP / int3 нет ничего достойного IST,Мы не разрешаем kprobes в небольшом количестве мест в ядре, которые работают на CPL0 с недопустимым стеком, а 32-битные ядра всегда использовали обычные шлюзы прерываний для #BP.

Кроме того, мы не делаемt разрешить kprobes в местах, где есть usergs в режиме ядра, поэтому «параноик» также не нужен.

В свете этой уязвимости я пытаюсь понять последнее предложение / абзац в коммитесообщение.Я понимаю, что запись IST ссылается на один из (предположительно) «известных исправных» указателей стека в таблице стека прерываний, который можно использовать для обработки прерываний.Я также понимаю, что #BP относится к исключению точки останова (эквивалентному INT3), и что kprobes является механизмом отладки, который, как утверждается, работает только в нескольких местах в ядре с уровнем привилегий кольца 0 (CPL0).

Но я полностью потерян в следующей части, которая может быть из-за того, что "usergs" - опечатка, и я просто упускаю то, что предполагалось:

Кроме того, мы нене разрешать kprobes в местах, где есть usergs в режиме ядра, поэтому «параноик» также не нужен.

Что означает это утверждение?

1 Ответ

0 голосов
/ 11 мая 2018

usergs ссылается на инструкцию x86-64 swapgs , которая обменивает gs с внутренним сохраненным значением GS для ядра, чтобы найти стек ядра из точки входа syscall.Свопы также меняют кешированную информацию о сегменте gsbase, а не перезагружают из GDT на основе самого значения gs.(wrgsbase может изменять базу GS независимо от GDT / LDT)

Дизайн AMD заключается в том, что syscall не изменяет RSP для указания на стек ядра и не 't чтение / запись любой памяти, поэтому syscall само по себе может быть быстрым.Но затем вы входите в ядро ​​со всеми регистрами, содержащими их значения в пространстве пользователя.См. Почему Windows64 использует соглашение о вызовах, отличное от всех других операционных систем на x86-64? , где приведены ссылки на обсуждения в списке рассылки между разработчиками ядра и архитекторами AMD в ~ 2000 году, в которых были изменены настройки syscall и swapgs, чтобы сделать его пригодным для использования до продажи каких-либо процессоров AMD64.


Очевидно, отслеживание того, является ли GS ядром или пользовательским значением, сложно для обработки ошибок : нет никакого способасказать: «Я хочу ядро ​​сейчас»;Вы должны знать, следует ли запускать swapgs или нет в любом пути обработки ошибок.Единственная инструкция - это своп, а не установка одного на другое.

Чтение комментариев в arch/x86/entry/entry_64.S например https://github.com/torvalds/linux/blob/9fb71c2f230df44bdd237e9a4457849a3909017d/arch/x86/entry/entry_64.S#L1267 (из текущего Linux), в котором упоминаются usergs, и следующий блоккомментариев описывает выполнение swapgs перед переходом к некоторому коду обработки ошибок с ядром gsbase.

IIRC, ядро ​​Linux [gs:0] содержит блок информации о потоке по самым низким адресам стека ядра для этого потока,Блок включает указатель стека ядра (как абсолютный адрес, не относящийся к gs).

Я не удивлюсь, если эта ошибка в основном обманывает ядро ​​при загрузке ядра rsp от пользователяуправляемый gsbase, или иным образом испортит счётчик swapgs, так что в какой-то момент у него будет неправильный gs.

...