Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

A developer’s guide to secure coding with FORTIFY_SOURCE

July 4, 2023
Sandipan Roy
Related topics:
CompilersRuntimesC, C#, C++SecuritySecure Coding
Related products:
Red Hat Enterprise Linux

Share:

    Secure coding is essential to building robust and resilient software that is less susceptible to exploitation by attackers. One way to ensure secure coding is to use a feature called FORTIFY_SOURCE. In this article, we will explore FORTIFY_SOURCE and how it can be used to enhance the security of your code.

    What is FORTIFY_SOURCE?

    FORTIFY_SOURCE is a feature available in the GNU C Library that provides runtime protection against certain types of security vulnerabilities. Specifically, FORTIFY_SOURCE detects and prevents buffer overflow and formats string vulnerabilities, which are two common types of vulnerabilities that attackers can exploit to take control of a system or steal sensitive data.

    How does FORTIFY_SOURCE work?

    FORTIFY_SOURCE works by providing enhanced versions of certain C library functions that can detect when a buffer overflow or format string vulnerability is about to occur. When a vulnerable function is called, FORTIFY_SOURCE checks the size of the buffer being used and ensures that it is not being overrun. If an overflow or vulnerability is detected, FORTIFY_SOURCE immediately terminates the program to prevent further damage.

    For example, consider the following code snippet:

    char buffer[8]; 
    
    strcpy(buffer, "hello world");

    In this code, the strcpy function is used to copy the "hello world" string into the buffer variable. However, the buffer variable is only allocated eight bytes of memory, which is not enough to hold the entire string. This results in a buffer overflow vulnerability that can be exploited by attackers.

    If FORTIFY_SOURCE is enabled, the strcpy function is replaced by a secure version that checks the size of the buffer and prevents an overflow from occurring. In this case, the program would terminate before the vulnerability could be exploited.

    Consider another code snippet:

    char password[16];
    
    scanf("%s", password);

    In this code, the scanf function is used to read input from the user and store it in the password variable. However, the scanf function does not perform any bounds checking, which means that if the user enters more than 16 characters, a buffer overflow vulnerability could occur.

    To mitigate this vulnerability using FORTIFY_SOURCE, you can use the secure version of scanf, called scanf_s, which checks the size of the buffer and prevents an overflow from occurring. Here's how the code would look using scanf_s:

    char password[16];
    
    scanf_s("%15s", password, sizeof(password));

    In this code, scanf_s takes an additional parameter that specifies the maximum number of characters that can be read from the user. In this case, we set the maximum length to 15, which leaves one byte for the null terminator that is added to the end of the string.

    By using scanf_s instead of scanf, we can prevent buffer overflow vulnerabilities in our code.

    How to use FORTIFY_SOURCE

    To use FORTIFY_SOURCE in your code, you must first ensure that it is enabled in your development environment. FORTIFY_SOURCE is typically enabled or disabled by invoking D_FORTIFY_SOURCE compiler flags. It is enabled by default in rpm macros and used when building all packages, but other uses of GCC need to explicitly enable it.

    Follow these steps:

    1. Compile your code using a compiler that supports FORTIFY_SOURCE. Most modern C compilers, such as GCC and Clang, support this feature.

    2. Enable FORTIFY_SOURCE using the appropriate compiler flag. The flag may vary depending on your compiler and version, but for GCC, you can use the -D_FORTIFY_SOURCE=2 flag to enable the feature.

    3. Compile your code with the appropriate optimization level. FORTIFY_SOURCE is most effective when the code is compiled with optimization enabled, so be sure to use at least -O1 optimization level.

    Here's an example command to compile your code with FORTIFY_SOURCE enabled using GCC:

    gcc -D_FORTIFY_SOURCE=2 -O1 -o myprogram myprogram.c

    Once your code is compiled with FORTIFY_SOURCE enabled, the enhanced secure library functions provided by the feature will automatically replace the standard C library functions, such as strcpy, scanf, and printf. This means that any calls to these functions in your code will be automatically replaced with the secure versions provided by FORTIFY_SOURCE.

    Once FORTIFY_SOURCE is enabled, you can use the enhanced secure library functions provided by the feature instead of the standard C library functions. For example, you can use strncpy_s instead of strcpy to safely copy a string into a buffer.

    It is important to note that FORTIFY_SOURCE does not provide complete protection against all types of security vulnerabilities. It only protects against buffer overflow and format string vulnerabilities. Therefore, it is important to use other secure coding practices in conjunction with FORTIFY_SOURCE to ensure that your code is as secure as possible.

    Advanced usage of FORTIFY_SOURCE

    When using FORTIFY_SOURCE, you can specify a level of protection between 0 and 3. The higher the level, the more security features are enabled. The default level is 1.

    FORTIFY_SOURCE=3 provides the highest level of protection and includes all the security features of levels 1 and 2, plus additional checks for potentially dangerous constructs in the code. These additional checks are designed to detect a wider range of security issues, including:

    • Dangerous use of memcpy and memmove functions.

    • Dangerous use of snprintf, vsnprintf, and similar functions.

    • Dangerous use of string manipulation functions like strtok, strncat, and strpbrk.

    However, it's important to note that enabling FORTIFY_SOURCE=3 may have some performance implications, as it adds additional code to perform the security checks. Therefore, it might be desirable to use a lower level of protection in performance critical code but the programmer must be mindful of additional security risks.

    To enable FORTIFY_SOURCE=3, you can use the -O2 optimization level in addition to the -D_FORTIFY_SOURCE=3 flag when compiling your code with GCC. Here's an example command to enable FORTIFY_SOURCE=3:

    gcc -D_FORTIFY_SOURCE=3 -O2 -o myprogram myprogram.c

    FORTIFY_SOURCE=3 provides the highest level of protection against security issues in C and C++ programs, but it may come at a performance cost. Therefore, it's important to carefully consider the level of protection you need and balance it with the performance requirements of your application.

    How to check FORTIFY_SOURCE

    In this example, we're copying a string that is longer than the size of the buf array, which can lead to a buffer overflow if FORTIFY_SOURCE is not enabled.

    #include <stdio.h>
    
    #include <string.h>
    
    
    
    int main() {
    
        char buf[10];
    
        strcpy(buf, "1234567890");
    
        printf("%s\n", buf);
    
        return 0;
    
    }

    To enable FORTIFY_SOURCE, we can compile the code with the -O2 optimization flag and the -D_FORTIFY_SOURCE=2 preprocessor flag:

    gcc -O2 -D_FORTIFY_SOURCE=2 -o test test.c

    Now when we run the program, we should see a runtime error indicating that a buffer overflow has occurred.

    *** buffer overflow detected ***: ./test terminated
    
    Aborted (core dumped)

    Also, we can use objdump to examine the compiled binary and look for references to FORTIFY_SOURCE. We can use the following command:

    objdump -R test

    This will show us the dynamic relocations table for our binary, which includes information about any shared libraries or symbols used by the program.

    If FORTIFY_SOURCE is enabled, we should see a reference to the symbol __strcpy_chk in the relocations table, which is a fortified version of the strcpy function that performs runtime checks for buffer overflows.

    Here's an example of what the output might look like if FORTIFY_SOURCE is enabled:

    test:     file format elf64-x86-64
    
    
    
    DYNAMIC RELOCATION RECORDS
    
    ...
    
    0000000000601018 R_X86_64_JUMP_SLOT  __strcpy_chk@GLIBC_2.3.4
    
    ...

    This indicates that our program is using the fortified __strcpy_chk function, which is provided by the GNU C library and performs runtime checks to prevent buffer overflows.

    Examining the dynamic relocation table of our compiled binary with objdump, we can check if FORTIFY_SOURCE is enabled and ensure that our code is properly secured against common security issues.

    We can also use checksec tool which primarily used for assessing the security features and hardening options of an executable or shared object file. While it is not specifically designed to check for the presence of FORTIFY_SOURCE in a binary, it can provide valuable information about the overall security posture of the program.

    When using checksec to assess a binary that has been compiled with FORTIFY_SOURCE, it can indicate the presence of certain security features that are commonly enabled by FORTIFY_SOURCE, such as stack canaries or enhanced buffer overflow protections. checksec can also detect other security mitigations that may have been enabled during compilation, such as Address Space Layout Randomization (ASLR) or Data Execution Prevention (DEP).

    Lets see the output of running checksec against our test program:

    $ checksec --file=./test
    
    RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
    Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   test
    

    In the output, we can observe the following several security features being reported.

    • Full RELRO indicates that all relocations have been resolved at load time, providing protection against certain types of attacks like GOT (Global Offset Table) overwrite attacks.
    • Canary found: The presence of a stack canary indicates the usage of a security mechanism designed to detect stack-based buffer overflows. FORTIFY_SOURCE often enables stack canaries to protect against these types of vulnerabilities.
    • NX enabled: NX (Non-Executable) marking prevents the execution of code in memory regions that are intended for data. This feature enhances security by preventing the execution of injected or malicious code.
    • PIE enabled: Position Independent Executable (PIE) makes the binary's base address random, providing Address Space Layout Randomization (ASLR) to thwart memory-based attacks. Fortify Source can be used in combination with PIE to strengthen the overall security of the executable.

    While this output doesn't explicitly state the usage of FORTIFY_SOURCE, the presence of stack canaries and other security features suggests that the binary may have been compiled with FORTIFY_SOURCE or similar security-enhancing techniques. To confirm the usage of FORTIFY_SOURCE, it's best to refer to the build configuration or examine the compiler flags and options used during the compilation process.

    FORTIFY_SOURCE improves code security

    FORTIFY_SOURCE is a valuable feature that can enhance the security of your code by providing runtime protection against buffer overflow and format string vulnerabilities. By enabling FORTIFY_SOURCE in your development environment and using secure library functions, you can reduce the risk of security vulnerabilities in your code. Remember that FORTIFY_SOURCE is just one tool in your toolbox and should be used in conjunction with other secure coding practices to ensure the security of your code.

    For more information, refer to these articles:

    • Security Technologies: FORTIFY_SOURCE
    • Enhance application security with FORTIFY_SOURCE
    • Broadening compiler checks for buffer overflows in FORTIFYSOURCE
    • Hardening ELF binaries using Relocation Read-Only (RELRO)

    Related Posts

    • Broadening compiler checks for buffer overflows in _FORTIFY_SOURCE

    • Toward _FORTIFY_SOURCE parity between Clang and GCC

    • How to improve application security using _FORTIFY_SOURCE=3

    • 3 steps toward improving container security

    Recent Posts

    • A deep dive into Apache Kafka's KRaft protocol

    • Staying ahead of artificial intelligence threats

    • Strengthen privacy and security with encrypted DNS in RHEL

    • How to enable Ansible Lightspeed intelligent assistant

    • Why some agentic AI developers are moving code from Python to Rust

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    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
    © 2025 Red Hat

    Red Hat legal and privacy links

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

    Report a website issue