🛡️ Clang Hardening Cheat Sheet: 10 лет спустя Ровно 10 лет назад ребята из Quarkslab выпустили свою знаменитую шпаргалк
Ровно 10 лет назад ребята из Quarkslab выпустили свою знаменитую шпаргалку по харденингу (усилению безопасности) бинарников с помощью Clang. За это время ландшафт угроз изменился до неузнаваемости, а сам компилятор обзавёлся мощнейшими механизмами защиты.
Разработчики обновили гайд под современные реалии. Вот ключевые выжимки и новые флаги, которые стоит внедрить в свои CI/CD пайплайны уже сегодня, если вы пишете на C/C++:
1. Безопасность памяти и проверки выходов за границы
• -D_GLIBCXX_ASSERTIONS — включает встроенные проверки в стандартной библиотеке C++ (например, контроль границ при обращении к элементам std::vector или std::string). Минимальный оверхед, огромная польза.
• -fstrict-flex-arrays=3 — ужесточает контроль за размерами гибких массивов в структурах, предотвращая популярные out-of-bounds уязвимости.
• -fstack-clash-protection — защита от атак типа Stack Clash. Компилятор генерирует код, который циклически "прощупывает" стек, не позволяя атакующему перепрыгнуть через защитную страницу (guard page).
2. Защита указателей и контроль потока выполнения (CFI)
Современный Clang делает упор на аппаратные фичи процессоров (особенно актуально для ARM64):
• -mbranch-protection=standard — включает одновременно PAC (Pointer Authentication Code) для подписи адресов возврата и BTI (Branch Target Identification) для предотвращения несанкционированных переходов. Это мощный барьер против ROP/JOP атак.
3. Очистка следов в памяти (Zeroing Registers)
• -fzero-call-used-regs=all-gpr — заставляет компилятор очищать (обнулять) универсальные регистры перед выходом из функции. Это предотвращает утечку конфиденциальных данных (например, криптографических ключей), которые могли остаться в регистрах после вычислений.
4. Ограничения линкера (Linker Flags)
Помимо классических -Wl,-z,relro и -Wl,-z,now, авторы рекомендуют:
• -Wl,-z,nodlopen — запрещает динамическую загрузку библиотеки через dlopen() во время выполнения (если архитектура приложения этого не требует).
• -Wl,-z,noexecstack — строго разграничивает права: стек только для данных, исполнение кода там запрещено.
5. Обновлённый FORTIFY_SOURCE
В современных версиях Clang механизм -D_FORTIFY_SOURCE=3 стал намного умнее благодаря встроенным функциям __builtin_dynamic_object_size. Теперь компилятор умеет проверять размеры буферов (в функциях вроде memcpy, snprintf, strtok) даже в тех случаях, когда размер выделяемой памяти становится известен только на этапе выполнения (runtime).
https://blog.quarkslab.com/clang-hardening-cheat-sheet-ten-years-later.html
#cpp #programming
👉 @cpp_lib