Skip to content

AD5001: EnablePositionIndependentExecutableMachO

Summary

Property Value
ID AD5001
Name EnablePositionIndependentExecutableMachO
Category Security
Severity Error
Applies to Mach-O (macOS, iOS)

Description

A Position Independent Executable (PIE) on macOS allows the operating system to load the executable at a random address each time it runs. This is required for full ASLR (Address Space Layout Randomization) protection.

How It Works

The rule checks the Mach-O header for:

  1. MH_PIE flag in the header flags
  2. For executables (not shared libraries, which are always position independent)

Why This Matters

Position Independent Executables are the foundation of security on Apple platforms. Without PIE, ASLR cannot protect the main executable, leaving attackers with predictable code locations to exploit.

ASLR on Apple Platforms

macOS and iOS use aggressive ASLR:

With PIE:
  0x100000000 + random → Executable base
  Different on every launch
  Attacker must guess or leak address

Without PIE (legacy):
  0x100000000 (fixed) → Executable base
  Same address every time
  Attacker knows exactly where code is

iOS App Store Requirement

Apple mandates PIE for iOS:

Platform PIE Requirement
iOS App Store Required (rejected without)
macOS App Store Required
macOS unsigned Strongly recommended
watchOS/tvOS Required

Entropy Comparison

Configuration Randomization
No PIE None (fixed address)
PIE on 64-bit High (up to 21 bits)

ROP Gadget Impact

Without PIE:
  pop rdi; ret @ 0x100001234  (always same address)
  Attacker pre-builds gadget chain

With PIE:
  pop rdi; ret @ 0x1????1234  (base unknown)
  Attacker must leak code address first
  Adds exploitation complexity

Defense Chain

PIE enables the full Apple security stack:

PIE → ASLR effective → Code signing meaningful
    → Hardened Runtime useful → Notarization protective

Performance on Apple Silicon

PIE is essentially free on Apple Silicon:

Architecture PIE Overhead
Apple M1/M2/M3 None measurable
Intel x86_64 <1%
iOS ARM64 None measurable

PC-relative addressing makes PIE cost-free.

  • Full ASLR: Executable code location randomized
  • ROP mitigation: Gadget addresses unpredictable
  • Required on iOS: Mandatory for App Store
  • macOS default: Required for system protections

Resolution

Clang/Xcode

PIE is enabled by default on modern macOS. To explicitly enable:

# Compile and link with PIE
clang -pie source.c -o binary

# Or set position independent code flag
clang -fPIE -pie source.c -o binary

Xcode Build Settings

In Xcode project settings: 1. Select target → Build Settings 2. Search for "Position Independent" 3. Set "Generate Position-Dependent Executable" to No

Or in xcconfig:

GCC_DYNAMIC_NO_PIC = NO

CMake

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

Makefile

CFLAGS += -fPIE
LDFLAGS += -pie

When to Suppress

This rule rarely needs suppression on modern macOS:

  • Kernel extensions: Different loading mechanism
  • Boot code: Pre-ASLR environment
  • Very old compatibility: macOS 10.6 and earlier

Caveats

  • PIE has been default since OS X 10.7 (Lion)
  • Required for iOS App Store submission
  • Some legacy code may disable PIE

macOS Security Requirements

macOS Version PIE Requirement
10.5 Optional
10.7+ Default enabled
10.15+ Expected for notarization
11.0+ (ARM) Required

References