Что такое ретполин и как он работает?
для того, чтобы смягчить против ядра или кросс-процесс раскрытия памяти (Spectre атаки), ядро Linux1 будет скомпилирован с новой опцией,-mindirect-branch=thunk-extern представил gcc для выполнения косвенных вызовов через так называемый retpoline.
это, кажется, недавно изобретенный термин, как поиск Google оказывается только очень недавнее использование (как правило, все в 2018 году).
что такое ретполин и как это происходит это предотвратит недавние атаки на раскрытие информации ядра?
1 это не специфично для Linux, однако-похоже, что подобная или идентичная конструкция используется как часть стратегии смягчения последствий на других ОС.
2 ответов:
статьи упомянутый sgbj в комментариях, написанных полом Тернером Google, объясняет следующее гораздо более подробно, но я дам ему шанс:
насколько я могу собрать это вместе из ограниченной информации на данный момент, retpoline-это возвращение батут который использует бесконечный цикл, который никогда не выполняется, чтобы предотвратить спекуляцию ЦП на цели косвенного перехода.
основной подход можно увидеть в ветвь ядра Энди Клина решения этой проблемы:
он вводит новый
__x86.indirect_thunkвызов, который загружает цель вызова, чей адрес памяти (который я буду называтьADDR) хранится в верхней части стека и выполняет прыжок с помощьюRETинструкция. Затем сам thunk вызывается с помощью NOSPEC_JMP / CALL макрос, который использовался для замены многих (если не всех) косвенных вызовов и переходов. Макрос просто помещает цель вызова на стеке и устанавливает обратный адрес правильно, если это необходимо (обратите внимание на нелинейный поток управления):.macro NOSPEC_CALL target jmp 1221f /* jumps to the end of the macro */ 1222: push \target /* pushes ADDR to the stack */ jmp __x86.indirect_thunk /* executes the indirect jump */ 1221: call 1222b /* pushes the return address to the stack */ .endmразмещение
callв конце концов необходимо так, что когда косвенный вызов закончен, поток управления продолжается за использованиемNOSPEC_CALLмакрос, поэтому его можно использовать вместо обычногоcallсам стук выглядит следующим образом:
call retpoline_call_target 2: lfence /* stop speculation */ jmp 2b retpoline_call_target: lea 8(%rsp), %rsp retпоток управления может немного запутаться здесь, так что позвольте мне уточните:
callпомещает указатель текущей инструкции (метка 2) в стек.leaдобавляет 8 к указатель стека, фактически отбрасывая совсем недавно толкнул четверных, который является последним обратный адрес (на этикетке 2). После этого вершина стека снова указывает на реальный обратный адрес ADDR.retскачков*ADDRи сбрасывает указатель стека в начале вызова стек.в конце концов, все это поведение практически эквивалентно прыжку прямо в
*ADDR. Одно преимущество, которое мы получаем, заключается в том, что предсказатель ветвей используется для операторов return (Return Stack Buffer, RSB) при выполненииcallинструкция, предполагает, что соответствующийretоператор перейдет к метке 2.часть после метки 2 на самом деле никогда не выполняется, это просто бесконечный цикл, который бы теоретически заполнить конвейер инструкций с
JMPинструкция. С помощьюLFENCE,PAUSEили в более общем случае инструкция, вызывающая остановку конвейера инструкций, останавливает процессор от потери любой мощности и времени на это спекулятивное выполнение. Это потому, что в случае, если вызов retpoline_call_target вернется нормально, тоLFENCEбудет следующая инструкция, которая будет выполнена. Это также то, что предсказатель ветвей будет предсказывать на основе исходного обратного адреса (метки 2)цитата из руководства Intel по архитектуре:
инструкции, следующие за LFENCE, могут быть извлечены из памяти до LFENCE, но они не будут выполняться до завершения LFENCE.
обратите внимание, однако, что в спецификации никогда не упоминается, что LFENCE и PAUSE вызывают остановку конвейера, поэтому я немного читаю между строк здесь.
теперь вернемся к вашему изначальному вопросу: Информация о памяти ядра раскрытие возможно благодаря сочетанию двух идей:
хотя спекулятивное исполнение должно быть без побочных эффектов, когда спекуляция была неправильной, спекулятивное выполнение все еще влияет на иерархию кэша. Это означает, что когда загрузка памяти выполняется спекулятивно, она все еще может привести к удалению строки кэша. Это изменение в иерархии кэша можно определить путем тщательного измерения времени доступа к памяти, которое является сопоставляется с тем же набором кэша.
Вы даже можете пропустить некоторые биты произвольной памяти, когда исходный адрес считанной памяти был сам считан из памяти ядра.косвенный предсказатель ветвей процессоров Intel использует только самые нижние 12 бит исходной инструкции, поэтому легко отравить все 2^12 возможных историй предсказания с помощью адресов памяти, управляемых пользователем. Они могут тогда, когда косвенный скачок предсказан в ядре, быть спекулятивно выполняется с правами ядра. Используя боковой канал синхронизации кэша, вы можете таким образом утечка произвольной памяти ядра.
обновление: на список рассылки ядра, есть продолжающееся обсуждение, которое заставляет меня полагать, что ретполины не полностью смягчают Проблемы прогнозирования ветвей, так как когда буфер стека возврата (RSB) работает пустым, более поздние архитектуры Intel (Skylake+) возвращаются к уязвимому целевому буферу ветви (BTB):
Retpoline в качестве стратегии по смягчению последствий проскакивают косвенные филиалы для возвращения, чтобы избежать использования прогнозов, которые поступают из BTB, поскольку они могут быть отравлены злоумышленником. Проблема с Skylake+ заключается в том, что RSB underflow возвращается к использованию BTB предсказание, которое позволяет злоумышленнику взять под контроль спекуляции.
A retpoline предназначен для защиты против впрыска цели ветви (CVE-2017-5715) эксплуатировать. Это атака, в которой косвенная команда ветви в ядре используется для принудительного спекулятивного выполнения произвольного фрагмента кода. Выбранный код - это "гаджет", который каким-то образом полезен злоумышленнику. Например, код может быть выбран так, что будет утечка данных ядра через то, как он влияет на кэш. Retpoline предотвращает этот подвиг, просто заменив все косвенные инструкции ветви с возвращенной инструкцией.
Я думаю, что ключ к retpoline-это просто часть "ret", которая заменяет косвенную ветвь инструкцией возврата, чтобы процессор использовал предиктор стека возврата вместо предиктора ветви, который можно использовать. Если вместо этого была использована простая команда push и return, то код, который будет спекулятивно выполнен, будет кодом, который функция в конечном итоге вернется в любом случае, а не какой-то гаджет, полезный для злоумышленник. Главным преимуществом части trampoline, по-видимому, является сохранение стека возврата, поэтому, когда функция фактически возвращается к своему вызывающему объекту, это предсказывается правильно.
основная идея за впрыской цели ветви проста. Он использует тот факт, что процессор не записывает полный адрес источника и назначения ветвей в своих целевых буферах ветвей. Таким образом, злоумышленник может заполнить буфер, используя прыжки в своем собственном адресном пространстве, что приведет к прогнозированию хиты, когда определенный косвенный переход выполняется в адресном пространстве ядра.
обратите внимание, что retpoline не препятствует раскрытию информации ядра напрямую, он только предотвращает использование косвенных инструкций ветви для спекулятивного выполнения гаджета, который раскрывает информацию. Если злоумышленник может найти какие-то другие средства для спекулятивного выполнения гаджета, то retpoline не предотвращает атаку.
в статье Spectre Атаки: Эксплуатация Спекулятивное Исполнение Пол Кохер, Даниэль Генкин, Даниэль Грусс, Вернер Хаас, Майк Гамбург, Мориц Липп, Стефан Мангард, Томас Прешер, Майкл Шварц и Юваль Яром дают следующий обзор того, как можно использовать косвенные ветви:
Использование Косвенных Ветвей. рисунок от возвратно-ориентированного программирования (ROP), в этом методе злоумышленник выбирает гаджет С адреса пространство жертвы и влияния жертва, чтобы выполнить гаджет спекулятивно. В отличие от растеризации, злоумышленник не полагаться на уязвимость в коде жертвы. Вместо этого, злоумышленник тренирует Целевой буфер ветви (BTB) для неправильного предсказания ветви из косвенного ответвление инструкции на адрес гаджета, в результате чего спекулятивное исполнение гаджета. Пока умозрительно исполняется инструкции заброшены, их влияние на кэш не происходит возвратившегося. Эти эффекты могут быть использованы гаджетом для утечки чувствительный информация. Мы покажем, как, при тщательном подборе гаджета, это метод может быть использован для чтения произвольной памяти у жертвы.
To перепутав BTB, злоумышленник находит виртуальный адрес гаджета в адресном пространстве жертвы затем выполняет косвенные ветви к этому адрес. Это обучение выполняется из адресного пространства злоумышленника, и не имеет значения, что находится по адресу гаджета в адресное пространство злоумышленника; все, что требуется это ветка для обучения филиалы использовать один и тот же виртуальный адрес. (В факт, пока злоумышленник обрабатывает исключения, атака может работать даже если код не отображается на виртуальный адрес гаджета в адресном пространстве злоумышленника.) Также нет необходимости в полном совпадение исходного адреса филиала, используемого для обучения и адрес целевой ветви. Таким образом, злоумышленник имеет значительные гибкость в настройке обучение.
запись в блоге под названием чтение привилегированной памяти с боковым каналом команда Project Zero в Google предоставляет еще один пример того, как можно использовать целевую инъекцию ветви для создания рабочего эксплойта.
Comments