Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

Use compiler flags for stack protection in GCC and Clang

June 2, 2022
Serge Guelton Siddhesh Poyarekar
Related topics:
CompilersSecurity
Related products:
Red Hat Enterprise Linux

    A binary may be subject to a wide range of attacks, but smashing the stack for fun and profit is one of the most venerable ones. Stack-based attacks are also the lowest-cost form of attack: Stack layouts are quite predictable because data containing return addresses can be overwritten to gain control over program execution.

    Compiler developers have implemented a wide range of countermeasures in response. This article discusses the major stack protection mechanisms in the GNU Compiler Collection (GCC) and Clang, typical attack scenarios, and the compiler's attempts to prevent attacks.

    Stack canary

    A stack canary is the most rudimentary check for buffer overflows on the stack. The canary is an extra word of memory at the end of the stack frame with a value set at runtime. This value is presumably unknown to the attacker and checked for modification before jumping out of the function. A modification indicates the detection of a stack smashing followed by a termination routine.

    Stack canaries are added by GCC and Clang through these flags:

    • -fstack-protector
    • -fstack-protector-strong
    • -fstack-protector-all
    • -fstack-protector-explicit

    SafeStack and shadow stack

    This form of protection splits the stack into two distinct areas, storing precious variables and user variables in non-contiguous memory areas. The goal is to make it more difficult to smash one of the stacks from the other. This process occurs in hardware (e.g., x86_64 shadow stack) or in software such as LLVM's SafeStack.

    GCC and Clang add shadow stack through this flag:

    • -mshstk

    Clang adds SafeStack through this flag:

    • -fsanitize=safe-stack

    Fortified source

    The GNU C library (glibc) provides alternate implementations of some commonly used functions to smash the stack by copying a given amount of bytes from one address to another. These implementations typically use compiler support to check for memory bounds of objects. If an operation overflows these bounds, it would cause programs to terminate. This defense is called FORTIFY_SOURCE and the Red Hat blog has an excellent post on the subject.

    GCC and Clang select fortified sources using the preprocessor flag -D_FORTIFY_SOURCE=<n> with an optimization level greater than -O0. A higher <n> corresponds to greater protection. However, there may be a tradeoff in performance, and some programs that conform to the standard may fail due to stricter security checks. GCC (version 12 and later) and Clang (version 9.0 and later) support <n> up to 3.

    Control flow integrity

    Return-oriented programming (ROP) uses an initial stack smash to take control of an indirect jump and then executes an arbitrary sequence of instructions. One countermeasure to this kind of attack is to ensure that jump addresses and return addresses are correct by using hardware support or pure software.

    GCC and Clang can generate support code for Intel's Control-flow Enforcement Technology (CET) through this compiler flag:

    • -fcf-protection=[full]

    GCC and Clang can also generate support code for Branch Target Identification (BTI) on AArch64 using:

    • -mbranch-protection=none|bti|pac-ret+leaf|pac-ret[+leaf+b-key]|standard

    In addition to these flags, which require hardware support, Clang provides a software implementation of control flow integrity.

    • -fsanitize=cfi

    Stack allocation control

    The following options have an impact on the stack allocation. These options are not necessarily designed to provide extra security, but they may be a nice side-effect.

    On an x86 target, GCC and Clang provide the ability to automatically allocate a discontiguous stack when running out of stack memory. The -fsplit-stack activates this behavior.

    When using the GNU linker, it is possible to pass a stack limit to the program, reading from a symbol or a register. This process is supported by GCC using:

    • -fstack-limit-register
    • -fstack-limit-symbol

    These stack-allocated arrays are a common entry point for a stack-based attack. The Clang compiler makes it possible to reduce the attack surface by disallowing this pattern, subsequently preventing the use of stack-allocated arrays. The code -fno-stack-array enables this process.

    Stack usage and statistics

    Most stack usage consists of either call stack information or fixed-sized allocations in the form of local variables. There is, however, a facility to allocate dynamically sized objects on the stack by using the alloca() function or using variable-length arrays (VLAs). alloca() usage with sizes can be user-controlled. This is a common target for overflowing stacks or making them clash with other maps in memory. As a result, a well-behaved application must always keep track of them. Both GCC and Clang provide ways to control alloca() and stack usage to prevent clashes at the outset.

    The following flags allow finer control over stack usage in applications and provide a warning when alloca() or VLA cross developer-defined thresholds:

    • -Wframe-larger-than
    • -Walloca
    • -Walloca-larger-than
    • -Wvla -Wvla-larger-than

    There are also recursion checks as well as higher-level checks on stack usage to help developers get better control of the stack behavior.

    Here is a full list of warnings implemented in GCC:

    • -Wstack-usage
    • -fstack-usage
    • -Walloca
    • -Walloca-larger-than
    • -Wvla
    • -Wvla-larger-than
    • -Wframe-larger-than
    • -mwarn-dynamicstack (s390x)
    • -Wstack-protector
    • -Wtrampolines
    • -Winfinite-recursion

    And here is a list of the warnings implemented in Clang:

    • -fstack-usage
    • -Walloca
    • -Wframe-larger-than
    • -Wstack-usage

    Summary

    Both GCC and Clang provide a wide range of compiler flags to prevent stack-based attacks. Some of these flags relate to a specific kind of exploit. Others introduce generic protection. And some flags give feedback like warnings and reports to the user, providing a better understanding of the behavior of the stack program. Depending on the attack scenario, code size constraints, and execution speed, compilers provide a wide range of tools to address the attack.

    Last updated: August 3, 2022

    Recent Posts

    • Tekton joins the CNCF as an incubating project

    • Federated identity across the hybrid cloud using zero trust workload identity manager

    • Confidential virtual machine storage attack scenarios

    • Introducing virtualization platform autopilot

    • Integrate zero trust workload identity manager with Red Hat OpenShift GitOps

    What’s up next?

    Linux server image

    The Intermediate Linux Cheat Sheet introduces developers and system administrators to more Linux commands they should know.

    Get the free cheat sheet
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.