====== 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.
→ [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:units:alloc|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 =====
* ''[[lyx_-_programmiersprache:units:alloc|std.alloc]]'' — Speicherverwaltung (wird intern von MetaSafeVerify genutzt)
* ''[[lyx_-_programmiersprache:units:fs_ext|std.fs_ext]]'' — Fstat, Dateilesen
Letzte Aktualisierung: 2026-06-06