Security-related flags and options for C compilers

Overview

Getting the maximum of your C compiler, for security

Introduction

This guide is intended to help you determine which flags you should use to compile your C Code using GCC, Clang or MSVC, in order to:

  • detect the maximum number of bugs or potential security problems.
  • enable security mitigations in the produced binaries.
  • enable runtime sanitizers to detect errors (overflows, race conditions, etc.) and make fuzzing more efficient.

Disclaimer:

The flags selected and recommended here were chosen to maximize the number of classes of detected errors which could have a security benefit when enabled. Code generation options (such as -fstack-protector-strong) can also have performance impacts. It is up to you to assess the impact on your code base and choose the right set of command line options.

Comments are of course welcome.

GCC TL;DR

Detailed page

Always use the following warnings and flags on the command line:

-O2
-Werror
-Wall -Wextra -Wpedantic -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 -Wformat-security -Wnull-dereference -Wstack-protector -Wtrampolines -Walloca -Wvla -Warray-bounds=2 -Wimplicit-fallthrough=3 -Wtraditional-conversion -Wshift-overflow=2 -Wcast-qual -Wstringop-overflow=4 -Wconversion -Warith-conversion -Wlogical-op -Wduplicated-cond -Wduplicated-branches -Wformat-signedness -Wshadow -Wstrict-overflow=4 -Wundef -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wstack-usage=1000000 -Wcast-align=strict
-D_FORTIFY_SOURCE=2
-fstack-protector-strong -fstack-clash-protection -fPIE 
-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code

On legacy code bases, some of the warnings may produce some false positives. On code where the behavior is intended, pragmas can be used to disable the specific warning locally.

Run debug/test builds with sanitizers (in addition to the flags above): AddressSanitizer + UndefinedBehaviorSanitizer:

-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=leak -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=bounds-strict -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow
export ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_invalid_pointer_pairs=2

If your program is multi-threaded, run with -fsanitize=thread (incompatible with ASan).

Finally, use -fanalyzer to spot potential issues.

Clang TL;DR

Detailed page

First compile with:

-O2
-Werror
-Walloca -Wcast-qual -Wconversion -Wformat=2 -Wformat-security -Wnull-dereference -Wstack-protector -Wstrict-overflow=3 -Wvla -Warray-bounds -Warray-bounds-pointer-arithmetic -Wassign-enum -Wbad-function-cast -Wconditional-uninitialized -Wconversion -Wfloat-equal -Wformat-type-confusion -Widiomatic-parentheses -Wimplicit-fallthrough -Wloop-analysis -Wpointer-arith -Wshift-sign-overflow -Wshorten-64-to-32 -Wswitch-enum -Wtautological-constant-in-range-compare -Wunreachable-code-aggressive 
-D_FORTIFY_SOURCE=2
-fstack-protector-strong -fsanitize=safe-stack -fPIE -fstack-clash-protection
-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code

On legacy code bases, some of the warnings may produce some false positives. On code where the behavior is intended, pragmas can be used to disable the specific warning locally.

Run debug/test builds with sanitizers (in addition to the flags above):

AddressSanitizer + UndefinedBehaviorSanitizer:

-fsanitize=address -fsanitize=leak -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=bounds-strict -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=integer -fsanitize-no-recover
export ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_invalid_pointer_pairs=2

If your program is multi-threaded, run with -fsanitize=thread (incompatible with ASan).

Finally, use scan-build to spot potential issues.

In addition, you can build production code with -fsanitize=integer -fsanitize-minimal-runtime -fsanitize-no-recover to catch integer overflows.

Microsoft Visual Studio 2019 TL;DR

Detailed page

  • Compile with /Wall /sdl /guard:cf /guard:ehcont /CETCOMPAT
  • Use ASan with /fsanitize=address
  • Analyze your code with /analyze

Tips

References

Written by Raphaël Rigo and reviewed by Sarah Zennou @ Airbus Security lab, 2021.

Contributing

Please open an issue if you notice any error, imprecision or have comments or improvements ideas.

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Comments
  • Unknown sanitizer options in Clang 12 (Fedora 34)

    Unknown sanitizer options in Clang 12 (Fedora 34)

    First of all, thank you very much for this useful list and explanations; it really helps extracting maximum power out of compilers and sanitizers.

    I have a few questions about some options.

    I have a Fedora 34 with Clang 12 installed, according to clang -v:

    clang version 12.0.1 (Fedora 12.0.1-1.fc34)
    Target: x86_64-unknown-linux-gnu
    

    I tried compiling a simple program using the options in the "Clang TL;DR" list, while also using the options for "AddressSanitizer + UndefinedBehaviorSanitizer", that is:

    clang err.c -O2 -Walloca -Wcast-qual -Wconversion -Wformat=2 -Wformat-security -Wnull-dereference \
    -Wstack-protector -Wstrict-overflow=3 -Wvla -Warray-bounds -Warray-bounds-pointer-arithmetic \
    -Wassign-enum -Wbad-function-cast -Wconditional-uninitialized -Wconversion -Wfloat-equal \
    -Wformat-type-confusion -Widiomatic-parentheses -Wimplicit-fallthrough -Wloop-analysis -Wpointer-arith \
    -Wshift-sign-overflow -Wshorten-64-to-32 -Wswitch-enum -Wtautological-constant-in-range-compare \
    -Wunreachable-code-aggressive -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fsanitize=safe-stack \
    -fPIE -fstack-clash-protection -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code -fsanitize=address \
    -fsanitize=leak -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=bounds-strict \
    -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=integer -fsanitize-no-recover
    

    I got the following error message:

    clang-12: error: unknown argument: '-fsanitize-no-recover'
    clang-12: error: unsupported argument 'bounds-strict' to option 'fsanitize='
    clang-12: error: invalid argument '-fsanitize=safe-stack' not allowed with '-fsanitize=leak'
    

    Indeed, there is a mention elsewhere in the page of option -fno-sanitize-recover, so it seems that -fsanitize-no-recover might be a typo. Could you please confirm it? Or is it a different option?

    About -fsanitize=bounds-strict, I found references to it on Google but only for GCC, not for Clang/LLVM. But I couldn't find a definitive list of options concerning all sanitizers, so maybe my Clang is missing them? Could you please confirm, or offer more details about the version of Clang you are using where this option works?

    About the incompatibility between SafeStack and Leak, I couldn't find any mentions in their documentation, but they don't typically list all incompatibilities (which would be hard to do and keep up-to-date), so I wonder if I took a bit too literally the comment "Run debug/test builds with sanitizers (in addition to the flags above)", by combining all flags. Or is there a way to run them together? I'd appreciate if you could clarify it (or just confirm that, indeed, mixing both does not work).

    Finally, after removing -fsanitize=leak, I still got an error: clang-12: error: invalid argument '-fsanitize=safe-stack' not allowed with '-fsanitize=address'. So, I ended up removing -fsanitize=safe-stack and putting back -fsanitize=leak, and this time I had no more errors. Once again, I wonder if this is specific to my configuration.

    opened by maroneze 2
  • Warn about -fsanitize=integer for unsigned integers

    Warn about -fsanitize=integer for unsigned integers

    First of all, great work! Thanks for compiling all this very useful information :-)

    Regarding clang's -fsanitize=integer option, the sanitizer might be a little picky when it comes to unsigned integers arithmetic and left shift operations. According to 6.2.5.9 of ISO C99, unsigned integers "can never overflow" (https://frama-c.com/download/frama-c-rte-manual.pdf), while the sanitizer will trigger a "runtime error" whenever a left shift on an unsigned integer will overflow a primitive unsigned integer type size or when an arithmetic operation does so. Nonetheless, such operations are quite common e.g. when developing big int or cryptographic libraries.

    It might be useful to document the ways of deactivating explicitly such errors (especially if the integer sanitizer is used for production) while keeping the other undefined behaviors using -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base.

    Regards,

    opened by rb-anssi 1
  • Invalid -Wlogical-op option for clang

    Invalid -Wlogical-op option for clang

    Hello, Thanks for this repo, it's great! I think there is a small error in the clang TL;DR section of the README; it seems that the -Wlogical-op option is GCC only and is not supported by clang. It is not listed in the reference. This is what I get with clang-12 -Wlogical-op foo.c -o foo:

    warning: unknown warning option '-Wlogical-op'; did you mean '-Wlong-long'? [-Wunknown-warning-option]
    
    opened by egirault 1
  • clang+-ftrivial-auto-var-init=pattern

    clang+-ftrivial-auto-var-init=pattern

    According to https://reviews.llvm.org/D64742 pattern zero works when used in conjunction with -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang (mandatory for C++, optional for C). Have you tried?

    opened by szennou 1
  • about

    about "disable the warnings that have too much false positives"

    Strongly disagree with that statement: if you used early in the development phase (and not compiling the code with security flags just before going into production), the false positive rate should not be that high

    opened by szennou 1
  • about

    about "-Wshorten-64-to-32: warn on 64 bits truncation (long to int for example)"

    C norm specifies that sizeof(long) >= sizeof(int). Note the ">=". I suggest to either remove your example or add "on architectures where sizeof(long) < sizeof(int)"

    opened by szennou 0
  • Control Flow Integrity and Shadow Stack?

    Control Flow Integrity and Shadow Stack?

    Currently, for the GCC 12 and Clang 11 TL;DR, I don't see the control flow integrity flag mentioned on the detailed page... is this because it is Intel specific? -fcf-protection=full

    In some other references, I see recommendations to enable the following flag for Intel x86 as well: -mshstk

    opened by hiowaguy 1
  • Moar options!

    Moar options!

    -D_FORTIFY_SOURCE=3 exists now.

    -ftrivial-auto-var-init=zero is in GCC 12+ and Clang.

    -fsanitize=bounds -fsanitize-undefined-trap-on-error for trivial checking of known-size arrays.

    -fstrict-flex-arrays will be in GCC 13+ and Clang 16+, but likely requires some very careful management of some header files, especially anything using the very ancient struct sockaddr. But it'll gain coverage of trailing arrays that would otherwise be ignored by FORTIFY and sanitize=bounds.

    opened by kees 1
This is a database of 180.000+ symbols containing Equities, ETFs, Funds, Indices, Futures, Options, Currencies, Cryptocurrencies and Money Markets.

Finance Database As a private investor, the sheer amount of information that can be found on the internet is rather daunting.

Jeroen Bouma 1.4k Dec 31, 2022
poro is a LCU interface to change some lol's options.

poro is a LCU interface to change some lol's options. with this program you can: change your profile icon change your profiel background image ch

João Dematte 2 Jan 5, 2022
Expose multicam options in the Blender VSE headers.

Multicam Expose multicam options in the Blender VSE headers. Install Download space_sequencer.py and swap it with the one that comes with the Blender

null 4 Feb 27, 2022
A web application (with multiple API project options) that uses MariaDB HTAP!

Bookings Bookings is a web application that, backed by the power of the MariaDB Connectors and the MariaDB X4 Platform, unleashes the power of smart t

MariaDB Corporation 4 Dec 28, 2022
This is a calculator of strike price distance for options.

Calculator-of-strike-price-distance-for-options This is a calculator of strike price distance for options. Options are a type of derivative. One strat

André Luís Lopes da Silva 4 Dec 30, 2022
Utility to play with ADCS, allows to request tickets and collect information about related objects

certi Utility to play with ADCS, allows to request tickets and collect information about related objects. Basically, it's the impacket copy of Certify

Eloy 185 Dec 29, 2022
This application demonstrates IoTVAS device discovery and security assessment API integration with the Rapid7 InsightVM.

Introduction This repository hosts a sample application that demonstrates integrating Firmalyzer's IoTVAS API with the Rapid7 InsightVM platform. This

Firmalyzer BV 4 Nov 9, 2022
Linux Security and Monitoring Scripts

Linux Security and Monitoring Scripts These are a collection of security and monitoring scripts you can use to monitor your Linux installation for sec

Andre Pawlowski 65 Aug 27, 2022
Backup dc registry - A simple POC that abuses Backup Operator privileges to remote dump SAM, SYSTEM, and SECURITY

Backup Operator Registry Backup to Domain Compromise A simple POC that abuses Ba

Horizon 3 AI Inc 57 Dec 18, 2022
A curated list of awesome things related to Pydantic! 🌪️

Awesome Pydantic A curated list of awesome things related to Pydantic. These packages have not been vetted or approved by the pydantic team. Feel free

Marcelo Trylesinski 186 Jan 5, 2023
Explore related sequences in the OEIS

OEIS explorer This is a tool for exploring two different kinds of relationships between sequences in the OEIS: mentions (links) of other sequences on

Alex Hall 6 Mar 15, 2022
This repo is related to Google Coding Challenge, given to Bright Network Internship Experience 2021.

BrightNetworkUK-GCC-2021 This repo is related to Google Coding Challenge, given to Bright Network Internship Experience 2021. Language used here is py

Dareer Ahmad Mufti 28 May 23, 2022
Programming labs for 6.S060 (Foundations of Computer Security).

6.S060 Labs This git repository contains the code for the labs in 6.S060. In these labs, you will add a series of security features to a photo-sharing

MIT PDOS 10 Nov 2, 2022
A sandpit for textual related things

A sandpit repo for testing textual related things.

Craig Gumbley 1 Nov 8, 2021
Given tool find related trending keywords of input keyword

blog_generator Given tool find related trending keywords of input keyword (blog_related_to_keyword). Then cretes a mini blog. Currently its customised

Shivanshu Srivastava 2 Nov 30, 2021
Extra scripts to improve user experience related to OpenTaiko

OpenTaiko-Utils Extra scripts to improve user experience related to OpenTaiko osu2tja /!\ IMPORTANT NOTE /!\ Converted charts that aren't yours are fo

null 2 Dec 25, 2022
Would upload anything I do with/related to brainfuck

My Brainfu*k Repo Basically wanted to create something with Brainfu*k but realized that with the smol brain I have, I need to see the cell values real

Rafeed 1 Mar 22, 2022
This is sample project needed for security course to connect web service to database

secufaku This is sample project needed for security course to "connect web service to database". Why it suits alignment purpose It connects to postgre

Mark Nicholson 6 May 15, 2022
Streamlit component to display topics from Streamlit's community forum related to any exception.

streamlit-forum Streamlit component to display topics from Streamlit's community forum related to any exception. Installation pip install streamlit-fo

Snehan Kekre 7 Jul 15, 2022