Когда и как использовать функцию защиты стека GCC?


я включил -Wstack-protector предупреждение при компиляции проекта, над которым я работаю (коммерческий многоплатформенный игровой движок C++, компиляция на Mac OS X 10.6 с GCC 4.2). Этот флаг предупреждает о функциях, которые не будут защищены от разрушения стека, даже если это. GCC выдает некоторые предупреждения при построении проекта:

не защитная функция: нет буфера длиной не менее 8 байт
не защищает локальные переменные: переменная длина буфер

для первого предупреждения я обнаружил, что можно настроить минимальный размер буфера, который должен иметь буфер при использовании в функции, чтобы эта функция была защищена от разрушения стека: --param ssp-buffer-size=X может использоваться, где X по умолчанию равно 8 и может быть всего 1.

для второго предупреждения я не могу подавить его появление, если я не перестану использовать -Wstack-protector.

  1. когда -fstack-protector использоваться? (как, например, все время во время dev, или просто при отслеживании ошибок вниз?)
  2. когда -fstack-protector-all использоваться?
  3. что это -Wstack-protector говоришь мне? Это предполагает, что я уменьшаю минимальный размер буфера?
  4. если да, то есть ли какие-либо недостатки, чтобы положить размер до 1?
  5. получается, что -Wstack-protector Это не тот флаг, который вы хотите включить в любое время, если вы хотите построить без предупреждения. Это правда?
2 52

2 ответа:

стек-защита стратегии закаливание, а не Стратегии отладки. Если ваша игра поддерживает сеть или иным образом содержит данные, поступающие из неконтролируемого источника, включите ее. Если у него нет данных, поступающих откуда-то неконтролируемо, не включайте его.

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

для решений, ориентированных на отладку, посмотрите на такие вещи, как mudflap.

Что касается вашего конкретного вопросы:

  1. используйте Stack protector, если вы получаете данные из неконтролируемых источников. Ответ на этот вопрос, вероятно, да. Так что используй его. Даже если у вас нет данных из неконтролируемых источников, вы, вероятно, в конечном итоге или уже делаете и не осознаете этого.
  2. защита стек для всех буферов может быть использована, если вы хотите дополнительную защиту в обмен на производительность. От версии gcc4.4.2 руководство:

    - fstack-protector

    выдавать дополнительный код для проверки переполнения буфера, такие как стек разбивая атаки. Это делается путем добавления переменной guard в функции с уязвимыми объектами. Это включает в себя функции, которые вызывают alloca, и функции с буферами размером более 8 байт. Охранники инициализируются при вводе функции, а затем проверяются при выходе из функции. Если проверка защиты завершается неудачно, выводится сообщение об ошибке и программа завершает работу.

    - fstack-protector-все

    Как-fstack-протектор за исключением того, что все функции защищены.

  3. предупреждения говорят вам, какие буферы защита стека не может защитить.

  4. это не обязательно означает, что вы уменьшаете свой минимальный размер буфера, и при размере 0/1 это то же самое, что и stack-protector-all. Он только указывает вам на это, чтобы вы могли, если решите перестроить код так, чтобы буфер защищен.
  5. нет, эти предупреждения не представляют проблемы, они просто указывают информацию для вас. Не используйте их регулярно.

вы действительно не должны заботиться о предупреждении для нормальной сборки. Это скорее информационное сообщение. Я надеюсь, что очевидно, что у вас есть неотъемлемая проблема безопасности с буферами переменного размера в стеке; получите неправильный расчет размера, и вы откроете большую дыру.