Skip to content

AD5004: UseFortifiedFunctionsMachO

Summary

Property Value
ID AD5004
Name UseFortifiedFunctionsMachO
Category Security
Severity Warning
Applies to Mach-O (macOS/iOS)

Description

FORTIFY_SOURCE replaces dangerous libc functions like strcpy, sprintf, and memcpy with bounds-checked versions that can detect buffer overflows at runtime.

Compile with -D_FORTIFY_SOURCE=2 and -O2 or higher optimization level to enable this protection.

How It Works

The rule checks for the presence of fortified function symbols such as:

  • __memcpy_chk
  • __strcpy_chk
  • __sprintf_chk
  • __snprintf_chk
  • And other *_chk variants

These symbols indicate that FORTIFY_SOURCE is enabled.

Why This Matters

FORTIFY_SOURCE transparently replaces dangerous C library functions with bounds-checked versions on macOS. This catches buffer overflows that would otherwise lead to exploitable vulnerabilities, with virtually no source code changes required.

How FORTIFY_SOURCE Works

// Your code:
char dest[10];
strcpy(dest, source);  // Dangerous if source > 10 bytes

// With FORTIFY_SOURCE=2, compiled as:
char dest[10];
__strcpy_chk(dest, source, 10);  // Knows dest is 10 bytes
                                  // Aborts if source > 10

Protected Functions

Category Functions
String strcpy, strcat, sprintf, snprintf
Memory memcpy, memmove, memset
Wide char wcscpy, wcscat
BSD extensions strlcpy, strlcat

FORTIFY_SOURCE Levels

Level Behavior Overhead
_FORTIFY_SOURCE=1 Compile-time only Zero
_FORTIFY_SOURCE=2 + Runtime checks Very low
_FORTIFY_SOURCE=3 + Variable sizes Low

Optimization Requirement

FORTIFY_SOURCE needs optimization to work:

Build Type FORTIFY Active
-O0 (Debug) NO
-O1+ YES
-O2 (Release) YES

Debug builds don't get FORTIFY protection!

Xcode Integration

Default Xcode behavior:
  Debug: -O0, no FORTIFY
  Release: -O2, FORTIFY can work

To enable:
  Add _FORTIFY_SOURCE=2 to Preprocessor Macros
  Or add -D_FORTIFY_SOURCE=2 to Other C Flags

Detection Example

char buf[16];
snprintf(buf, 64, "%s", user_input);  // Wrong size!

// Without FORTIFY: Buffer overflow, maybe exploit
// With FORTIFY: Runtime abort, safe crash

Verification

# Check for fortified functions
nm binary | grep _chk

# Expected output:
#   U ___snprintf_chk
#   U ___strcpy_chk
  • Runtime buffer overflow detection: Catches overflows that static analysis misses
  • Transparent protection: No source code changes required
  • Low overhead: Minimal performance impact in most cases
  • Defense in depth: Complements other protections like stack canaries

Resolution

Xcode

  1. Select your target in Xcode
  2. Go to Build Settings → Apple Clang - Preprocessing
  3. Add _FORTIFY_SOURCE=2 to Preprocessor Macros
  4. Ensure optimization level is -O2 or higher

Command Line (Clang)

clang -D_FORTIFY_SOURCE=2 -O2 source.c -o binary

CMake

add_compile_definitions(_FORTIFY_SOURCE=2)
add_compile_options(-O2)

Makefile

CFLAGS += -D_FORTIFY_SOURCE=2 -O2

When to Suppress

This rule may be suppressed for:

  • Debug builds: FORTIFY_SOURCE requires optimization (-O1 or higher)
  • Swift-only applications: Swift has built-in bounds checking
  • Binaries without libc calls: Pure computational code

Caveats

  • Requires optimization level -O1 or higher
  • Only protects calls where buffer size is known at compile time
  • May cause crashes instead of silent corruption (this is intentional)
  • AD3030 - ELF version of this check
  • AD5003 - Stack canary protection

References