Last active
September 30, 2025 05:39
-
-
Save sueszli/b655396d5373c01a2bff6a7b3803ad1e to your computer and use it in GitHub Desktop.
ossf compiler hardening with cmake
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cmake_minimum_required(VERSION 3.27 FATAL_ERROR) | |
| project(demo LANGUAGES C) | |
| set(CMAKE_C_STANDARD 23) | |
| set(CMAKE_C_STANDARD_REQUIRED ON) | |
| if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 14.0.0) | |
| message(FATAL_ERROR "GCC is outdated: ${CMAKE_C_COMPILER_VERSION}") | |
| endif() | |
| if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 16.0.0) | |
| message(FATAL_ERROR "Clang is outdated: ${CMAKE_C_COMPILER_VERSION}") | |
| endif() | |
| # | |
| # compiler hardening see: | |
| # https://github.com/ossf/wg-best-practices-os-developers/blob/main/docs/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C%2B%2B.md | |
| # | |
| add_compile_options( | |
| -O2 | |
| -Wall | |
| -Wextra | |
| -Wformat | |
| -Wformat=2 | |
| -Wconversion | |
| -Wsign-conversion | |
| -Wimplicit-fallthrough | |
| -Werror=format-security | |
| # more portable and explicit than -fhardened | |
| -U_FORTIFY_SOURCE | |
| -D_FORTIFY_SOURCE=3 | |
| -D_GLIBCXX_ASSERTIONS | |
| -fstrict-flex-arrays=3 | |
| -fstack-protector-strong | |
| # deprecated c calls | |
| -Werror=implicit | |
| -Werror=incompatible-pointer-types | |
| -Werror=int-conversion | |
| # multithreading with pthreads | |
| -fexceptions | |
| # for shared libraries use `-fPIC` | |
| -fPIE | |
| ) | |
| # build mode specific | |
| if(CMAKE_BUILD_TYPE STREQUAL "Release") | |
| add_compile_options( | |
| -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -ftrivial-auto-var-init=zero | |
| ) | |
| else() | |
| add_compile_options(-Werror) | |
| endif() | |
| # os specific | |
| if(CMAKE_SYSTEM_NAME STREQUAL "Linux") | |
| add_compile_options(-fstack-clash-protection) | |
| add_link_options( | |
| -pie | |
| -Wl,-z,nodlopen | |
| -Wl,-z,noexecstack | |
| -Wl,-z,relro | |
| -Wl,-z,now | |
| -Wl,--as-needed | |
| -Wl,--no-copy-dt-needed-entries | |
| ) | |
| endif() | |
| # compiler specific | |
| if(CMAKE_C_COMPILER_ID MATCHES "GNU") | |
| # from gcc-15 add `-fzero-init-padding-bits=all` | |
| add_compile_options(-Wtrampolines -Wbidi-chars=any) | |
| endif() | |
| if(CMAKE_C_COMPILER_ID MATCHES "Clang") | |
| # nop | |
| endif() | |
| # architecture specific | |
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|i686|i386") | |
| add_compile_options(-fcf-protection=full) | |
| endif() | |
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64") | |
| add_compile_options(-mbranch-protection=standard) | |
| endif() | |
| # | |
| # sources | |
| # | |
| add_executable(demo demo.c) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Test C/C++ hardening flags | |
| // Copyright Open Source Security Foundation (OpenSSF) and its contributors | |
| // SPDX-License-Identifier: Apache-2.0 OR MIT | |
| #include <stdio.h> | |
| // Linux 5.10 solution: | |
| #if __has_attribute(__fallthrough__) | |
| #define fallthrough __attribute__((__fallthrough__)) | |
| #else | |
| #define fallthrough \ | |
| do { \ | |
| } while (0) /* fallthrough */ | |
| #endif | |
| int main(void) { | |
| int c = 0; | |
| switch (c) { | |
| case 1: | |
| printf("Hello\n"); | |
| fallthrough; | |
| case 0: | |
| printf("Goodbye\n"); | |
| fallthrough; | |
| default: | |
| printf("Default\n"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| FROM --platform=linux/amd64 ubuntu:24.04 | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| gcc-14 g++-14 \ | |
| clang-19 \ | |
| cmake make \ | |
| valgrind \ | |
| && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100 \ | |
| && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100 \ | |
| && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100 \ | |
| && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /workspace | |
| COPY . /workspace |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| DOCKER_RUN = docker run --rm -v $(PWD):/workspace main sh -c | |
| .PHONY: build-image | |
| build-image: | |
| docker build -t main . | |
| .PHONY: run-gcc | |
| run-gcc: build-image | |
| $(DOCKER_RUN) "mkdir -p /tmp/gcc-build && cd /tmp/gcc-build && cmake -DCMAKE_C_COMPILER=gcc /workspace && make && ./demo" | |
| .PHONY: run-clang | |
| run-clang: build-image | |
| $(DOCKER_RUN) "mkdir -p /tmp/clang-build && cd /tmp/clang-build && cmake -DCMAKE_C_COMPILER=clang /workspace && make && ./demo" | |
| .PHONY: fmt | |
| fmt: | |
| uvx --from cmakelang cmake-format --dangle-parens --line-width 120 -i CMakeLists.txt | |
| find . -name "*.c" -o -name "*.h" | xargs clang-format -i | |
| .PHONY: clean | |
| clean: | |
| docker rmi main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment