DedSec Project

Compiler Toolchains, Sanitizers, CFI and Binary Hardening — DedSec Project

Compiler Toolchains, Sanitizers, CFI and Binary Hardening Compilers are part of the security boundary because they transform source assumptions into machine-level behavior. This module…

Compilers are part of the security boundary because they transform source assumptions into machine-level behavior. This module explains optimization, undefined behavior, sanitizers, stack protection, CFI-related techniques, linker hardening, and reproducible builds as security engineering tools.

Learning objectives

By the end of this module you should be able to:

Deep concepts

1. Undefined behavior

In languages such as C/C++, undefined behavior allows the compiler to assume certain invalid states never occur. Security debugging must consider that optimized code may not preserve the intuitive behavior seen in an unoptimized build.

2. Sanitizers

AddressSanitizer, UndefinedBehaviorSanitizer, MemorySanitizer, and related tools detect classes of mistakes during testing. They trade performance/memory for visibility and are generally not substitutes for production hardening.

3. Stack and object protections

Stack canaries, fortified library calls, bounds-aware APIs, hardened allocators, and compiler diagnostics can turn silent memory corruption into earlier failures or eliminate common bug patterns.

4. Control-flow integrity

CFI-style protections constrain indirect control transfers according to a policy/type model. Their effectiveness depends on compilation coverage, language/runtime, dynamic linking, and where uninstrumented code remains.

5. Linker hardening

PIE, RELRO, non-executable mappings, symbol visibility, library search policy, and load-time configuration shape the binary attack surface. Verify actual produced binaries rather than assuming build flags took effect.

6. LTO and optimization

Link-time optimization can improve whole-program visibility but changes build reproducibility, debugging, and instrumentation. Security pipelines should test release-like optimization levels.

7. Toolchain provenance

The compiler, linker, SDK, sysroot, plugins, and build scripts are dependencies. Pin/verify toolchains appropriate to the threat model and keep a record of which toolchain produced each release.

8. Regression strategy

A fixed vulnerability should become a test: unit test, sanitizer test, fuzz regression input, static-analysis rule, or invariant. The goal is to prevent the bug class from silently returning.

Authorized exercises

Exercise 1 — Compile a harmless toy C program with and without common hardening flags and inspect the resulting binary properties—without developing an exploit

Compile a harmless toy C program with and without common hardening flags and inspect the resulting binary properties—without developing an exploit.

Exercise 2 — Use a sanitizer on intentionally buggy toy code to capture a diagnostic and explain root cause, object lifetime, and fix

Use a sanitizer on intentionally buggy toy code to capture a diagnostic and explain root cause, object lifetime, and fix.

Exercise 3 — Create a build-metadata record containing compiler version, flags, source hash, dependency lock, and output digest

Create a build-metadata record containing compiler version, flags, source hash, dependency lock, and output digest.

Knowledge checks

  1. Explain the most important trust boundary in Compiler Toolchains, Sanitizers, CFI and Binary Hardening without naming a security tool.
  2. Give one example where cryptographic or authentication success still does not imply authorization success.
  3. Describe one stale-state or replay condition relevant to this module.
  4. Identify one telemetry source that can support a strong conclusion and one blind spot it still leaves.
  5. Explain how you would turn a discovered weakness into a regression test rather than a one-time finding.

Guided study workflow