Skip to content

AD3014: NoTextRelocations

Summary

Property Value
ID AD3014
Name NoTextRelocations
Category Correctness
Severity Error
Applies to ELF (Linux/Unix)

Description

This rule checks that ELF binaries do not contain text relocations (TEXTREL). Text relocations require the .text (code) section to be writable during loading, which defeats W^X (Write XOR Execute) memory protections.

Why This Matters

Text relocations fundamentally break the W^X (Write XOR Execute) security model. When code must be writable, it becomes trivially exploitable—and the system loses one of its most important defenses.

What Are Text Relocations?

When code contains absolute addresses that must be adjusted at load time:

// Absolute address compiled into code:
movq $0x12345678, %rax   // Points to global variable

// At load time, linker must patch this address
// Requires .text section to be WRITABLE

The W^X Violation

Normal memory layout:
  .text  - Readable, Executable (not writable)
  .data  - Readable, Writable (not executable)

With TEXTREL:
  .text  - Readable, Writable, Executable
         = Attackers can inject code

Security Implications

Attack Without TEXTREL With TEXTREL
Code injection Blocked (W^X) Possible
GOT overwrite + ret2text Complex Easier
Exploit reliability Lower Higher

Performance Impact

TEXTREL prevents code sharing:

Without TEXTREL:
  Process A: Maps libc.so at 0x7fff1000
  Process B: Maps same pages (shared memory)
  Memory: 1 copy of libc code

With TEXTREL:
  Process A: Loads libc.so, patches addresses
  Process B: Must have own copy (different patches)
  Memory: Multiple copies of libc code

Hardened System Rejection

Many security-focused environments reject TEXTREL:

System TEXTREL Handling
SELinux (strict) Denied, won't load
grsecurity Denied by default
Android Rejected for NDK
Hardened Gentoo Compile error
OpenBSD Warnings, may reject

Common Causes and Fixes

Cause Fix
Non-PIC shared library Compile with -fPIC
Assembly with absolute addresses Use RIP-relative
Inline assembly Use proper constraints
Old precompiled objects Recompile from source

Detecting Text Relocations

# Check for TEXTREL tag
readelf -d binary | grep TEXTREL

# Find which object files cause it
scanelf -qT binary

# Detailed relocation info
readelf -r binary | grep -E 'R_X86_64_32|R_386_32'
  • Security: Writable code sections can be exploited for code injection attacks
  • Performance: Text relocations prevent code sharing between processes
  • RELRO incompatibility: Text relocations are incompatible with full RELRO protection
  • SELinux/hardened kernels: Many secure systems reject binaries with text relocations

Common Causes

  1. Non-PIC code in shared libraries: Code compiled without -fPIC
  2. Assembly code: Hand-written assembly without proper addressing
  3. Old/legacy code: Code written before PIE/PIC was standard

How to Fix

Compile with position-independent code

# For shared libraries
gcc -fPIC -shared -o libexample.so example.c

# For executables (PIE)
gcc -fPIE -pie -o myapp myapp.c

Fix assembly code

Use PC-relative addressing or GOT-relative addressing in assembly:

# Bad: absolute address
movq $my_global, %rax

# Good: RIP-relative (x86_64)
leaq my_global(%rip), %rax

Verify the fix

# Check for TEXTREL
readelf -d myapp | grep TEXTREL

# Alternative using scanelf
scanelf -qT myapp

Example

Fail: Binary has text relocations

0x0000000000000016 (TEXTREL)   0x0

Pass: No TEXTREL entry in dynamic section

See Also