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:
MH_PIEflag in the header flags- 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:
CMake¶
Makefile¶
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 |