Files
git.stella-ops.org/docs/contracts/init-section-roots.md
StellaOps Bot f1a39c4ce3
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
up
2025-12-13 18:08:55 +02:00

8.0 KiB

CONTRACT-INIT-ROOTS-401: Init-Section Synthetic Roots

Status: Published Version: 1.0.0 Published: 2025-12-13 Owners: Scanner Guild, Policy Guild, Signals Guild Unblocks: SCANNER-INITROOT-401-036, EDGE-BUNDLE-401-054, and downstream tasks

Overview

This contract defines how ELF/PE/Mach-O initialization sections (.init_array, .ctors, DT_INIT, etc.) are modeled as synthetic roots in reachability graphs. These roots represent code that executes during program load, before main(), and must be included in reachability analysis for complete vulnerability assessment.


1. Init-Section Categories

1.1 ELF Init Sections

Section/Tag Phase Order Description
.preinit_array / DT_PREINIT_ARRAY preinit 0-N Executed before dynamic linker init
.init / DT_INIT init 0 Single init function
.init_array / DT_INIT_ARRAY init 1-N Array of init function pointers
.ctors init after init_array Legacy C++ constructors
.fini / DT_FINI fini 0 Single cleanup function
.fini_array / DT_FINI_ARRAY fini 1-N Array of cleanup function pointers
.dtors fini after fini_array Legacy C++ destructors

1.2 PE Init Sections

Mechanism Phase Order Description
DllMain (DLL_PROCESS_ATTACH) init 0 DLL initialization
TLS callbacks init 1-N Thread-local storage callbacks
C++ global constructors init after TLS Via CRT init table
DllMain (DLL_PROCESS_DETACH) fini 0 DLL cleanup

1.3 Mach-O Init Sections

Section Phase Order Description
__mod_init_func init 0-N Module init functions
__mod_term_func fini 0-N Module termination functions

2. Synthetic Root Schema

2.1 Root Object in richgraph-v1

{
  "roots": [
    {
      "id": "root:init:0:sym:binary:abc123...",
      "phase": "init",
      "source": "init_array",
      "order": 0,
      "target_id": "sym:binary:abc123...",
      "binary_path": "/usr/lib/libfoo.so.1",
      "build_id": "gnu-build-id:5f0c7c3c..."
    }
  ]
}

2.2 Root ID Format

root:{phase}:{order}:{target_symbol_id}

Examples:

  • root:preinit:0:sym:binary:abc... - First preinit function
  • root:init:0:sym:binary:def... - DT_INIT function
  • root:init:1:sym:binary:ghi... - First init_array entry
  • root:main:0:sym:binary:jkl... - main() function
  • root:fini:0:sym:binary:mno... - DT_FINI function

2.3 Phase Enumeration

Phase Numeric Order Execution Time
load 0 Dynamic linker resolution
preinit 1 Before dynamic init
init 2 During initialization
main 3 Program entry (main)
fini 4 During termination

3. Root Discovery Algorithm

3.1 ELF Root Discovery

1. Parse .dynamic section for DT_PREINIT_ARRAY, DT_INIT, DT_INIT_ARRAY
2. For each array:
   a. Read function pointer addresses
   b. Resolve to symbol (if available) or emit unknown
   c. Create root with phase + order
3. Find _start, main, _init, _fini symbols and add as roots
4. Sort roots by (phase, order, target_id) for determinism

3.2 Handling Unresolved Targets

When init array contains address without symbol:

{
  "roots": [
    {
      "id": "root:init:2:unknown:0x12345678",
      "phase": "init",
      "source": "init_array",
      "order": 2,
      "target_id": "unknown:0x12345678",
      "resolved": false,
      "reason": "No symbol at address 0x12345678"
    }
  ],
  "unknowns": [
    {
      "id": "unknown:0x12345678",
      "type": "unresolved_init_target",
      "address": "0x12345678",
      "source": "init_array[2]"
    }
  ]
}

4. DT_NEEDED Dependency Modeling

4.1 Purpose

DT_NEEDED entries specify shared library dependencies. These execute their init code before the depending binary's init code.

4.2 Schema

{
  "dependencies": [
    {
      "id": "dep:libssl.so.3",
      "name": "libssl.so.3",
      "source": "DT_NEEDED",
      "order": 0,
      "resolved_path": "/usr/lib/x86_64-linux-gnu/libssl.so.3",
      "resolved_build_id": "gnu-build-id:abc..."
    }
  ]
}

4.3 Init Order with Dependencies

1. libssl.so.3 preinit → init
2. libcrypto.so.3 preinit → init
3. libc.so.6 preinit → init
4. main_binary preinit → init → main

5. Patch Oracle Integration

5.1 Oracle Expected Roots

{
  "expected_roots": [
    {
      "id": "root:init:*:sym:binary:*",
      "phase": "init",
      "source": "init_array",
      "required": true,
      "reason": "Init function must be detected for CVE-2023-XXXX"
    }
  ]
}

5.2 Oracle Forbidden Roots

{
  "forbidden_roots": [
    {
      "id": "root:preinit:*:*",
      "phase": "preinit",
      "reason": "Preinit code should not exist after patch"
    }
  ]
}

6. Policy Integration

6.1 Reachability State with Init Roots

When evaluating reachability:

  1. If vulnerable function is reachable from mainREACHABLE
  2. If vulnerable function is reachable from init roots → REACHABLE_INIT
  3. If vulnerable function is reachable only from finiREACHABLE_FINI

6.2 Policy DSL Extensions

# Require init-phase reachability for not_affected
rules:
  - name: init-reachability-required
    condition: |
      vuln.phase_reachable.includes("init") and
      reachability.confidence >= 0.8
    action: require_evidence

  - name: init-only-lower-severity
    condition: |
      reachability.reachable_phases == ["init"] and
      not reachability.reachable_phases.includes("main")
    action: reduce_severity
    severity_adjustment: -1

7. Evidence Requirements

7.1 Init Root Evidence Bundle

{
  "root_evidence": {
    "root_id": "root:init:0:sym:binary:...",
    "extraction_method": "dynamic_section",
    "source_offset": "0x1234",
    "target_address": "0x5678",
    "target_symbol": "frame_dummy",
    "evidence_hash": "sha256:...",
    "evidence_uri": "cas://binary/roots/sha256:..."
  }
}

7.2 CAS Storage Layout

cas://reachability/roots/{graph_hash}/
  init.json          # All init-phase roots
  fini.json          # All fini-phase roots
  dependencies.json  # DT_NEEDED graph
  evidence/
    root:{id}.json   # Per-root evidence

8. Determinism Rules

8.1 Root Ordering

Roots are sorted by:

  1. Phase (numeric: load=0, preinit=1, init=2, main=3, fini=4)
  2. Order within phase (numeric)
  3. Target ID (string, ordinal)

8.2 Root ID Canonicalization

root_id = "root:" + phase + ":" + order + ":" + target_id

All components lowercase, no whitespace.


9. Implementation Status

Component Location Status
ELF init parser NativeCallgraphBuilder.cs Implemented
Root model NativeSyntheticRoot Implemented
richgraph-v1 roots RichGraph.cs Implemented
Patch oracle roots PatchOracleComparer.cs Implemented
Policy integration - Pending
DT_NEEDED graph - Pending

10. Test Fixtures

Location: tests/Binary/fixtures/init-roots/

Fixture Description
elf-simple-init/ Binary with single init function
elf-init-array/ Binary with multiple init_array entries
elf-preinit/ Binary with preinit_array
elf-ctors/ Binary with .ctors section
elf-stripped-init/ Stripped binary with init
pe-dllmain/ PE DLL with DllMain
pe-tls-callbacks/ PE with TLS callbacks


Changelog

Version Date Author Changes
1.0.0 2025-12-13 Scanner Guild Initial contract for init-section roots