Теневая стековая память

Теневая стековая память (англ. shadow stack) в компьютерной безопасности — это механизм защиты сохранённого адрес возврата процедуры[1], например, от переполнения буфера стека. Сама теневая стековая память представляет собой второй, отдельный стек, который «отражает» стек вызовов программы. В пролог функции возвращаемый адрес сохраняется как в стеке вызовов, так и в теневой стековой памяти. В эпилог функции адрес возврата извлекается из обеих структур и сравнивается. Если записи адреса возврата расходятся, это считается атакой; типичной реакцией является завершение работы программы или оповещение системных администраторов о возможной попытке взлома. Теневая стековая память схожа по назначению с стековыми канареечными значениями, так как обе технологии служат для обеспечения целостности управляющего потока защищаемой программы, обнаруживая попытки изменить адрес возврата при эксплуатации уязвимостей[2].

Принцип работы

Теневая стековая память может реализовываться путём перекомпиляции программ с модифицированными прологами и эпилогами функций, с помощью динамической переработки двоичного кода, либо на уровне аппаратной поддержки. В отличие от стека вызовов, в котором также хранятся локальные переменные, переданные аргументы, сохранённые регистры и другие данные, теневая стековая память содержит, как правило, только вторую копию адреса возврата каждой функции.

Теневая стековая память обеспечивает более надёжную защиту адресов возврата, чем стековые канареечные значения, которые зависят от секретности своего значения и уязвимы к атакам с неразрывной записью. Для защиты самой теневой стековой памяти применяются защитные страницы или стратегия скрытия информации, затрудняющая злоумышленнику поиск места расположения теневого стека с целью изменения сохранённого адреса возврата.

Как и стековые канареечные значения, теневая стековая память не защищает другие данные стека, кроме адресов возврата, и потому не полностью предотвращает уязвимости, связанные с нарушением безопасности обращения к памяти.

В 2016 году компания Intel анонсировала поддержку теневой стековой памяти на аппаратном уровне в рамках технологии обеспечения целостности управляющего потока (Control-flow Enforcement Technology).

Проблемы совместимости

Использование теневой стековой памяти сопряжено с определёнными проблемами совместимости. В частности, после возникновения исключения или выполнения longjmp адрес возврата, извлечённый из вершины теневой стековой памяти, может не совпадать с соответствующим адресом из стека вызовов. Типичным решением этой проблемы является пошаговое извлечение адресов из теневой стековой памяти до совпадения с адресом из стека вызова, причём завершение программы происходит только в случае, если подходящего адреса там не находится.

В многопоточных программах, где для каждого потока создаётся отдельный стек вызовов, создаётся также и отдельная теневая стековая память для отражения соответствующего стека.

Примечания

  1. Delshadtehrani, Leila; Eldridge, Schuyler; Canakci, Sadullah; Egele, Manuel; Joshi, Ajay (1 января 2018). “Nile: A Programmable Monitoring Coprocessor”. IEEE Computer Architecture Letters [англ.]. 17 (1): 92—95. DOI:10.1109/LCA.2017.2784416. ISSN 1556-6056.
  2. Szekeres, Laszlo; Payer, Mathias; Wei, Tao; Song, Dawn (2003). “SoK: Eternal War in Memory” (PDF). IEEE Symposium on Security and Privacy [англ.]: 48—63. Дата обращения 2024-06-18.

Литература

Категории