
Privates End-to-End-Sanitizer-Reproduktionspaket für sechs GDCM-Befunde
Sechs Parser-/Codec-Defekte in GDCM, reproduziert auf v3.2.6 als Sanitizer-Fehler oder begrenzte Propagationsprüfungen. Jeder automatisierte Auslöser hat eine nahezu gültige Kontrolle, die das anfällige Signal nicht erzeugt. Befund 1 enthält zusätzlich ein instrumentiertes Kontrollfluss-Primitiv.
Gedacht für die Überprüfung durch Maintainer und Schwachstellen-Koordinatoren. Lesen Sie SAFETY.md, bevor
Sie irgendetwas ausführen.
manifest/targets.env:
| Name | Revision | Was es ist |
|---|
vulnerable | 9c71b163 | Tag v3.2.6 |
master | 2cd05d13 | Upstream-master-Snapshot, statisch überprüft; Laufzeitmatrix ausstehend |
fixed | nicht gesetzt | erst befüllen, wenn ein überprüfter Remediation-Commit existiert |
master ist ein datierter Snapshot, kein beweglicher Branch. Beide Revisionen sind aus dem
öffentlichen Repository erreichbar, sodass bootstrap.sh beide ohne jeglichen privaten Quellcode
vorbereiten kann.
Laufzeitnachweise in diesem Repository gelten für v3.2.6. Die weiteren Bereiche unten stammen aus der Quellcode-Historieninspektion; die betroffenen Muster sind auch im angepinnten Master- Snapshot weiterhin vorhanden.
| # | CWE | Quellcode-geprüfter Bereich | Erforderlicher Pfad |
|---|---|---|---|
| 1 | CWE-787 | v3.0.4 bis v3.2.7 | Multi-Frame-RLE-YBR_FULL_422-Lesen |
| 2 | CWE-787 | v2.0.16 bis v3.2.7 | JPEG2000-Kodierung/-Transkodierung |
| 3 | CWE-125 | v2.0.5 bis v3.2.7 | Segmentierte Palette-Analyse; LUT-Anwendung legt propagierte Werte offen |
| 4 | CWE-787 | v2.0.8 bis v3.2.7 | ImageRegionReader::ReadIntoBuffer; im Zusammenhang mit unvollständiger Präzisionsvalidierung nach CVE-2024-22373 |
| 5 | CWE-674 | v2.0.4 oder früher bis v3.2.7 | gewöhnliches Parsen verschachtelter Sequenzen |
| 6 | CWE-369 | v2.0.4 oder früher bis v3.2.7 | gewöhnliches RLE-Parsen mit NumSegments=0 |
fixtures/ - die inerten DICOM-Eingaben, SHA-256-gepinnt in manifest/expectations.json
und vor jedem Auslöserlauf verifiziertgenerators/ - deterministische, abhängigkeitsfreie Quellgeneratoren für jedes Fixtureharnesses/ - minimale Lese-/Kodier-/Dekodier-Harnesses; Befund 2 wird sowohl über
die gdcmconv-CLI als auch über die Bibliotheks-Transcode-API gezeigt, die ein Server aufrufen würdemanifest/expectations.json - maschinenlesbare Befehle, entscheidende Signale und
Akzeptanzkriterien für das fixed-Zielscripts/ - Vorbereitung des angepinnten Quellcodes, Sanitizer-Builds, begrenzte Ausführung, Bereinigungevidence/ - prägnante bereits beobachtete Ergebnisse, mit explizit genannten ungetesteten ZielenLICENSE - MIT-LizenzEine wegwerfbare Linux- oder macOS-Build-Umgebung mit Git, Python 3, CMake 3.20+, Ninja und
einer C++11-Toolchain (Clang oder GCC). Unter Ubuntu: git python3 cmake ninja-build clang zlib1g-dev. Setzen Sie CC/CXX, um stattdessen GCC zu verwenden.
Die Quellcode-Vorbereitung klont über HTTPS, es sei denn, GDCM_SOURCE_REPO verweist auf einen vorhandenen
lokalen Klon. Es wird kein SSH-Host verwendet.
Diese Befehle bereiten nur Quellcode und Build-Artefakte vor; sie öffnen kein Fixture.
./scripts/build-target.sh vulnerable asan debug
./scripts/build-target.sh vulnerable ubsan debug
./scripts/build-target.sh master asan debug
./scripts/build-target.sh master ubsan debug
Das dritte Argument ist das Profil. debug ist -O0 -g; release ist -O2 -g -DNDEBUG,
was GDCMs gdcm_debug_assert()s entfernt und der Art entspricht, wie Distributionen die
Bibliothek bauen. Die Matrix unter beiden auszuführen beantwortet die erste Frage, die ein Maintainer stellt,
nämlich ob die Berichte ein Artefakt eines assertion-fähigen Builds sind.
GDCM_SUPPORT_BROKEN_IMPLEMENTATION=ON ist GDCMs eigener Standard und wird unverändert gelassen.
Überschreiben Sie die konservative Parallelität mit JOBS=8.
Jeder Build schreibt build-info.json (Revision, Compiler, Flags, Plattform) in seinen GDCM-
Build-Baum, und jede Laufzusammenfassung bettet sie ein, sodass archivierte Nachweise selbsterklärend sind.
export GDCM_REPRO_ACK=I_UNDERSTAND_THIS_CRASHES_A_LOCAL_PROCESS
./scripts/run-matrix.sh vulnerable master --profile debug # alle automatisierten Fälle
./scripts/run-one.sh vulnerable f1 # ein Auslöser
./scripts/run-one.sh vulnerable f1 --control # seine Kontrolle
run-matrix.sh führt jeden automatisierten Fall für jedes Ziel aus, stoppt nicht beim ersten
Fehler und schreibt _runs/matrix-<stamp>.json sowie eine gerenderte
_runs/matrix-<stamp>.md. Der zweistufige f1-exploit-Fall bleibt manuell und wird
als solcher gemeldet, statt fälschlich als fehlgeschlagener automatisierter Fall klassifiziert zu werden.
Jedes Kind hat Core Dumps deaktiviert und ein 15-Sekunden-Timeout; Befund 5 erhält zusätzlich ein
begrenztes Stack-Limit. Ausgaben bleiben unter _runs/. Der Klassifizierer gleicht Sanitizer-Klasse
und betroffene Funktion ab, niemals Adressen, PIDs oder Quellcodezeilennummern.
Für vulnerable besteht ein Fall, wenn das entscheidende Signal erscheint und seine Kontrolle sauber bleibt.
Für master zeichnet der Runner die Beobachtung auf statt eines vorab erklärten Urteils.
Für fixed besteht ein Fall nur, wenn das Signal fehlt, kein anderes Sanitizer- oder fatales
Signal erscheint und der Harness ein erlaubtes sauberes Ergebnis zurückgibt. Diese Regeln sind
vorläufig, bis FIXED_REV einen tatsächlichen Patch benennt; sie müssen gegen das
beabsichtigte Ablehn-oder-Verarbeiten-Verhalten dieses Patches überprüft werden.
| Fall | Befund | Was er zeigt |
|---|---|---|
f1 | 1 | ASan-Heap-Schreiben in RLECodec::DecodeFragment |
f1-exploit | 1 | instrumentiertes Überschreiben benachbarter Objekte und indirekte Verzweigungskontrolle (Linux x86-64) |
f2 | 2 | ASan-Heap-Schreiben in opj_write_from_memory über gdcmconv --j2k |
f2-lib | 2 | dasselbe Schreiben über ImageChangeTransferSyntax::Change |
f3 | 3 | ASan-Heap-Lesen bei segmentierter Palette-Erweiterung |
f3-propagation | 3 | Out-of-Bounds-Bytes erreichen dekodierte Pixel, gemeldet als Anzahl |
f3-sentinel | 3 | ein begrenztes bekanntes Guard-Wort überschreitet die logische LUT-Grenze |
f4 | 4 | ASan-Heap-Schreiben bei JPEG2000-Region-Dekodierung |
f5 | 5 | ASan-Stack-Erschöpfung bei verschachtelten Sequenzelementen |
f6 | 6 | UBSan-Division durch Null bei RLE-Dekodierung; SIGFPE auf x86 |
Zwei weitere Harnesses sind Exploitability-Forschung statt Reproduktionsfälle und bauen nur im unsanitized Profil auf Linux x86-64:
| Harness | Befund | Was er belegt |
|---|---|---|
finding01_groom | 1 | die getestete glibc-Adjazenz, beobachtet über allokationsaufzeichnende Hooks |
finding03_leak | 3 | ein 131070-Byte-Overread kann einen build-spezifischen Bibliothekszeiger offenlegen |
evidence/v3.2.6-macos-arm64-debug.md zeichnet die abgeschlossene v3.2.6-Debug-Matrix auf,
einschließlich jeder Kontrolle und beider begrenzter Befund-3-Propagationsprüfungen.
evidence/v3.2.6-linux-x86_64-finding01-groom.md und
evidence/v3.2.6-linux-x86_64-finding03-leak.md zeichnen die beiden Exploitability-Ergebnisse
unten auf. Ergebnisse für aktuelles Master, die vollständige Release-Profil-Matrix und f1-exploit werden nicht
beansprucht, bis ihre Transkripte aufbewahrt sind.
./scripts/clean.sh
Die Bereinigung weigert sich, ohne den Paketmarker zu laufen, und entfernt nur _work, _build,
_generated, _runs und Python-Bytecode-Caches unterhalb dieses Repositorys. Aufbewahrte
Nachweise unter evidence/ werden nicht entfernt.
f1-exploit ist nur für Linux-x86_64 und wird von Hand ausgeführt; manifest/expectations.json enthält
die exakte Befehlssequenz. Unter dem deterministischen Allokationslayout des Harness testet es
drei separate Fakten, jeweils mit einem passenden Negativfall:
f1-Fixtures meldet Korruption, aber ausdrücklich
nicht Inhaltskontrolle, sodass die Prüfung falsifizierbar ist;Etwa die Hälfte der 8-Byte-Fenster innerhalb des 12288-Byte-Überlaufs akzeptiert einen beliebigen
Wert. Der Rest ist gekoppelt, weil DoYBRFull422 ein Quellbyte in zwei
Ausgabepositionen dupliziert; Offset 6144 ist eines der freien Fenster. Die Dekodierung von Frame 1 läuft zuletzt, also
ist es der Inhalt von Frame 1, der über die Allokation hinaus bestehen bleibt.
Der Harness zeichnet auf, ob ImageReader::Read() true zurückgibt, während das benachbarte Objekt
modifiziert wird. Ein erfolgreiches Linux-x86-64-Transkript muss aufbewahrt werden, bevor dieses
Ergebnis als beobachteter Nachweis beschrieben wird.
f1-exploit liefert sein eigenes Opfer-Layout, kann also nicht beantworten, ob ein unmodifizierter
Prozess dieses Layout hat. finding01_groom verwendet Stock-glibc, Standard-PIE und ASLR, mit
globalen Allokations-Hooks, die Allokationen aufzeichnen, aber nicht verschieben. In den aufbewahrten
Tests:
finding01-Harness stirbt auf dieselbe Weise ganz ohne Instrumentierung.Auf dem getesteten glibc-Build verursachte Befund 1 zuverlässig Denial of Service; es wurde kein Code-Execution-Pfad gefunden. Die getestete Geometrie war fest, und andere Allocatoren oder Plattformen könnten den Heap anders anordnen.
finding03_leak ist das stärkere Ergebnis. Im getesteten Build erreicht das Out-of-Bounds-Lesen
131070 Bytes, ein gdcm::ByteValue-vtable-Zeiger gelangt in dekodierte Pixel, und der
Harness leitet die Bibliotheks-Ladebasis unter Verwendung des bekannten vtable-Offsets dieses Builds ab. Dies ist ein
lokales API-Level-Offenlegungsergebnis: es erfordert LUT-Anwendung und Zugriff auf den dekodierten
Pixelpuffer. Es zeigt nicht, dass ein Netzwerkdienst diese Pixel zurückgibt.
Die beiden können hier nicht zu Code-Execution verkettet werden, und nicht nur, weil kein Opfer gefunden wurde: sie benötigen unterschiedliche PhotometricInterpretation-Werte, also zwei Dateien, und eine geleakte Basis ist nur nützlich, solange der leckende Prozess noch lebt.
Ein Sanitizer-Bericht beweist das angegebene Memory-Safety- oder Undefined-Behavior-Ereignis im
getesteten Prozess und in der getesteten Revision. f1-exploit testet Byte-Kontrolle und ein Überschreiben eines benachbarten Funktions-
zeigers unter einem instrumentierten Allocator, der absichtlich das Ziel-
Layout liefert. Es belegt dieses Layout nicht in einem unmodifizierten Consumer. Die aufbewahrten
finding01_groom-Versuche beobachteten dieses Layout für die getestete Geometrie und den glibc-
Build nicht.
Nichts davon beweist Remote-Erreichbarkeit in einem bestimmten Produkt, Persistenz oder Downstream-Anwendbarkeit. Das Erreichbarkeitsargument für ein gegebenes Deployment ist eine separate Behauptung, die im Offenlegungstext gemacht wird und nicht von diesem Paket.