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

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

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

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

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

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

2 ответа

Решение

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

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

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

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

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

    -fstack-протектор

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

    -fstack-протектор-все

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

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

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

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

Другие вопросы по тегам