std.meta_safe

Sicherer Post-Patching Runtime-Verifier: Liest die .meta_safe-ELF-Section aus /proc/self/exe, re-berechnet CRC32-Prüfsummen für jede Code-Page (4 096 Bytes) und meldet, ob das Binary seit dem Kompilieren unverändert ist. Die Section wird vom Compiler-Pass ms_appendMetaSafe() automatisch erzeugt, wenn --meta-safe gesetzt ist — kein manuelles Linking erforderlich. Auf x86_64 steht ein optimierter Fast-Path zur Verfügung.

Standard Library · std.alloc


Konzept

Der Lyx-Compiler legt beim Build eine ELF-Section .meta_safe an, die für jede 4 096-Byte-Page im .text-Segment einen Eintrag enthält:

Offset Größe Inhalt
0 4 Bytes Magic 0x4D455441 („META„)
4 4 Bytes Anzahl Pages (pageCount)
8 8 Bytes Tatsächliche .text-Länge in Bytes (codeLen)
16 + n×8 4 Bytes Page-Offset von .text-Start
16 + n×8 + 4 4 Bytes Gespeicherter CRC32 dieser Page

MetaSafeVerify öffnet /proc/self/exe, liest das gesamte Binary, lokalisiert die .meta_safe-Section über den ELF-Section-Header-Table, re-berechnet den CRC32 jeder Page und vergleicht mit den gespeicherten Werten.


Funktionen

Signatur Beschreibung
MetaSafeVerify(): int64 Prüft alle Code-Pages. Gibt 0 zurück wenn alle CRC32-Prüfsummen stimmen, −1 bei Fehler (korrupte Page, fehlende Section, kein Lesezugriff auf /proc/self/exe).
MetaSafeGetPageHash(pageIdx: int64): int64 Gibt den gespeicherten CRC32-Wert für Page pageIdx (0-basiert) zurück, oder −1 wenn pageIdx außerhalb des gültigen Bereichs liegt.

Verwendung

Integrity-Check beim Start

import std.meta_safe;
import std.io;

fn main(): void {
    var r := MetaSafeVerify();
    if (r != 0) {
        PrintLn("WARNUNG: Binary-Integrität verletzt!");
        // Sicherheitsreaktion: Abbruch, Logging, Alert …
        exit(1);
    }
    // Normaler Programmstart …
}

Page-Hash abrufen (Diagnose)

import std.meta_safe;
import std.io;

fn PrintPageHashes(count: int64): void {
    var i: int64 := 0;
    while (i < count) {
        var crc := MetaSafeGetPageHash(i);
        if (crc < 0) { break; }
        Print("Page " + IntToStr(i) + ": CRC32 = 0x");
        // CRC als Hex ausgeben …
        PrintLn(IntToStr(crc));
        i := i + 1;
    }
}

Periodische Laufzeit-Prüfung

import std.meta_safe;
import std.thread;

fn IntegrityWatchdog(): void {
    // In einem separaten Thread periodisch prüfen
    while (1 == 1) {
        if (MetaSafeVerify() != 0) {
            // Alarm schlagen …
        }
        sleep(30000);  // alle 30 Sekunden
    }
}


CRC32-Algorithmus

Die verwendete Polynomkonstante ist 0xEDB88320 (ISO 3309, PKZIP-kompatibel). Die Implementierung spiegelt exakt den Compiler-seitigen ms_crc32:

// CRC32 über len Bytes ab data:
//   crc = 0xFFFFFFFF
//   für jedes Byte b: crc = (crc >> 1) ^ (0xEDB88320 falls LSB gesetzt)
//   Rückgabe: crc ^ 0xFFFFFFFF


Hinweise

  • MetaSafeVerify öffnet /proc/self/exe und liest das gesamte Binary in den Heap — bei großen Binaries (> 10 MB) entsprechend Speicher einplanen.
  • Die Funktion ist nicht reentrant-sicher: mehrfache parallele Aufrufe aus verschiedenen Threads sind zu vermeiden.
  • MetaSafeVerify gibt −1 zurück wenn die .meta_safe-Section fehlt (d. h. das Binary wurde nicht mit --meta-safe gebaut oder der Abschnitt wurde gestripped).
  • Für Produktions-Deployments empfiehlt sich ein einmaliger Aufruf beim Programmstart; ein laufender Watchdog-Thread erhöht die Schutzwirkung gegen Live-Patching-Angriffe.
  • Die Section-Suche parst den ELF-Section-Header-Table direkt (keine externen Bibliotheken). Unterstützt werden ELF64-Binaries auf x86-64 Linux (mit dediziertem Fast-Path) und AArch64 (generischer Pfad).
  • Abgrenzung zu --integrity-check: --integrity-check (getriggert durch @integrity) erzeugt ein festes 8232-Byte-Format mit drei CRC32-Kopien des gesamten Code-Segments (TMR-Schema). --meta-safe erzeugt eine variable Section mit einem CRC32 pro 4 096-Byte-Page — feiner granular, direkt zugänglich via MetaSafeGetPageHash.
  • Verifizierte Rückgabewerte (Akzeptanztests): MetaSafeVerify()0 bei unverändert, −1 bei korrumpierter Page oder fehlender Section; MetaSafeGetPageHash(invalidIdx)−1.

Verwandte Units

  • std.alloc — Speicherverwaltung (wird intern von MetaSafeVerify genutzt)
  • std.fs_ext — Fstat, Dateilesen

Letzte Aktualisierung: 2026-06-06