Когда и как использовать функцию защиты стека GCC? - PullRequest
59 голосов
/ 27 октября 2009

Я включил предупреждение -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 ]

63 голосов
/ 25 ноября 2010

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

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

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

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

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...