Pacchetto privato di riproduzione del sanitizer end-to-end per sei risultati di GDCM
Sei difetti di parser/codec in GDCM, riprodotti sulla v3.2.6 come fallimenti dei sanitizer o controlli di propagazione limitati. Ogni trigger automatizzato ha un controllo quasi-valido che non produce il segnale vulnerabile. Il reperto 1 include anche una primitiva di flusso di controllo strumentata.
Destinato alla revisione da parte dei manutentori e dei coordinatori delle vulnerabilità. Leggere SAFETY.md prima di eseguire qualsiasi cosa.
manifest/targets.env:
| Nome | Revisione | Cos'è |
|---|
vulnerable | 9c71b163 | tag v3.2.6 |
master | 2cd05d13 | snapshot upstream master revisionato staticamente; matrice runtime in sospeso |
fixed | non impostato | popolare solo quando esiste un commit di remediation revisionato |
master è uno snapshot datato, non un branch in movimento. Entrambe le revisioni sono raggiungibili dal repository pubblico, quindi bootstrap.sh può preparare l'una o l'altra senza alcuna sorgente privata.
Le prove runtime in questo repository sono per la v3.2.6. Gli intervalli più ampi riportati di seguito provengono dall'ispezione della cronologia dei sorgenti; i pattern implicati rimangono anche nello snapshot master fissato.
| # | CWE | Intervallo ispezionato nei sorgenti | Percorso richiesto |
|---|---|---|---|
| 1 | CWE-787 | da v3.0.4 a v3.2.7 | lettura multi-frame RLE YBR_FULL_422 |
| 2 | CWE-787 | da v2.0.16 a v3.2.7 | codifica/transcodifica JPEG2000 |
| 3 | CWE-125 | da v2.0.5 a v3.2.7 | parsing di palette segmentate; l'applicazione della LUT espone valori propagati |
| 4 | CWE-787 | da v2.0.8 a v3.2.7 | ImageRegionReader::ReadIntoBuffer; correlato alla validazione di precisione incompleta dopo CVE-2024-22373 |
| 5 | CWE-674 | da v2.0.4 o precedente a v3.2.7 | parsing ordinario di sequenze annidate |
| 6 | CWE-369 | da v2.0.4 o precedente a v3.2.7 | parsing RLE ordinario con NumSegments=0 |
fixtures/ - gli input DICOM inerti, con SHA-256 fissato in manifest/expectations.json e verificati prima di ogni esecuzione del triggergenerators/ - generatori di sorgenti deterministici e senza dipendenze per ogni fixtureharnesses/ - harness minimali di lettura/codifica/decodifica; il reperto 2 è mostrato sia tramite la CLI gdcmconv sia tramite l'API di transcodifica della libreria che un server chiamerebbemanifest/expectations.json - comandi leggibili dalla macchina, segnali decisivi e criteri di accettazione per il target fixedscripts/ - preparazione dei sorgenti fissati, build con sanitizer, esecuzione limitata, puliziaevidence/ - risultati concisi già osservati, con i target non testati dichiarati esplicitamenteLICENSE - licenza MITUn ambiente di build Linux o macOS usa e getta con Git, Python 3, CMake 3.20+, Ninja e una toolchain C++11 (Clang o GCC). Su Ubuntu: git python3 cmake ninja-build clang zlib1g-dev. Impostare CC/CXX per usare GCC invece.
La preparazione dei sorgenti clona via HTTPS a meno che GDCM_SOURCE_REPO non punti a un clone locale esistente. Non viene usato alcun host SSH.
Questi comandi preparano solo sorgenti e artefatti di build; non aprono alcuna 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
Il terzo argomento è il profilo. debug è -O0 -g; release è -O2 -g -DNDEBUG, che elimina le gdcm_debug_assert() di GDCM e corrisponde a come le distribuzioni compilano la libreria. Eseguire la matrice con entrambi risponde alla prima domanda che un manutentore pone, ovvero se i report sono un artefatto di una build con le asserzioni abilitate.
GDCM_SUPPORT_BROKEN_IMPLEMENTATION=ON è il default di GDCM stesso e viene lasciato invariato. Sovrascrivere il parallelismo conservativo con JOBS=8.
Ogni build scrive build-info.json (revisione, compilatore, flag, piattaforma) nel proprio albero di build GDCM, e ogni riepilogo di esecuzione lo incorpora, così le prove archiviate sono auto-descrittive.
export GDCM_REPRO_ACK=I_UNDERSTAND_THIS_CRASHES_A_LOCAL_PROCESS
./scripts/run-matrix.sh vulnerable master --profile debug # all automated cases
./scripts/run-one.sh vulnerable f1 # one trigger
./scripts/run-one.sh vulnerable f1 --control # its control
run-matrix.sh esegue ogni caso automatizzato per ogni target, non si ferma al primo fallimento e scrive _runs/matrix-<stamp>.json più un _runs/matrix-<stamp>.md renderizzato. Il caso f1-exploit a due stadi rimane manuale ed è riportato come tale invece di essere classificato erroneamente come un caso automatizzato fallito.
Ogni processo figlio ha i core dump disabilitati e un timeout di 15 secondi; il reperto 5 riceve inoltre un limite di stack limitato. Gli output rimangono sotto _runs/. Il classificatore confronta la classe del sanitizer e la funzione implicata, mai indirizzi, PID o numeri di riga dei sorgenti.
Per vulnerable, un caso passa quando appare il segnale decisivo e il suo controllo rimane pulito. Per master, il runner registra l'osservazione invece di un verdetto predefinito. Per fixed, un caso passa solo quando il segnale è assente, non appare alcun altro sanitizer o segnale fatale, e l'harness restituisce un esito pulito consentito. Queste regole sono provvisorie finché FIXED_REV non indica una patch effettiva; devono essere riviste rispetto al comportamento previsto di rifiuto-o-elaborazione di quella patch.
| Caso | Reperto | Cosa mostra |
|---|---|---|
f1 | 1 | scrittura heap ASan in RLECodec::DecodeFragment |
f1-exploit | 1 | sovrascrittura strumentata di oggetto adiacente e controllo di branch indiretto (Linux x86-64) |
f2 | 2 | scrittura heap ASan in opj_write_from_memory tramite gdcmconv --j2k |
f2-lib | 2 | la stessa scrittura tramite ImageChangeTransferSyntax::Change |
f3 | 3 | lettura heap ASan nell'espansione di palette segmentate |
f3-propagation | 3 | byte fuori limite raggiungono i pixel decodificati, riportati come conteggio |
f3-sentinel | 3 | una parola di guardia nota e limitata attraversa il limite logico della LUT |
f4 | 4 | scrittura heap ASan nella decodifica di regione JPEG2000 |
f5 | 5 | esaurimento dello stack ASan su elementi di sequenza annidati |
f6 | 6 | divisione per zero UBSan nella decodifica RLE; SIGFPE su x86 |
Altri due harness sono ricerca di sfruttabilità piuttosto che casi di riproduzione, e si compilano solo nel profilo senza sanitizer su Linux x86-64:
| Harness | Reperto | Cosa stabilisce |
|---|---|---|
finding01_groom | 1 | l'adiacenza glibc testata, osservata tramite hook di registrazione delle allocazioni |
finding03_leak | 3 | una sovralettura di 131070 byte può esporre un puntatore di libreria specifico della build |
evidence/v3.2.6-macos-arm64-debug.md registra la matrice debug v3.2.6 completata, inclusi ogni controllo ed entrambi i controlli limitati di propagazione del reperto 3.
evidence/v3.2.6-linux-x86_64-finding01-groom.md e evidence/v3.2.6-linux-x86_64-finding03-leak.md registrano i due risultati di sfruttabilità riportati di seguito. I risultati su master corrente, la matrice completa del profilo release e f1-exploit non sono dichiarati finché i loro transcript non vengono conservati.
./scripts/clean.sh
La pulizia rifiuta di essere eseguita senza il marker del pacchetto e rimuove solo _work, _build, _generated, _runs e le cache di bytecode Python sotto questo repository. Le prove conservate sotto evidence/ non vengono rimosse.
f1-exploit è solo per Linux-x86_64 e viene eseguito manualmente; manifest/expectations.json contiene la sequenza esatta di comandi. Sotto il layout di allocazione deterministico dell'harness verifica tre fatti separati, ciascuno con un caso negativo abbinato:
f1 semplice, segnala corruzione ma esplicitamente non controllo del contenuto, quindi il controllo è falsificabile;Circa la metà delle finestre di 8 byte all'interno dell'overflow di 12288 byte accetta un valore arbitrario. Le restanti sono accoppiate, perché DoYBRFull422 duplica un byte sorgente in due posizioni di output; l'offset 6144 è una delle finestre libere. La decodifica del frame 1 viene eseguita per ultima, quindi è il contenuto del frame 1 che persiste oltre l'allocazione.
L'harness registra se ImageReader::Read() restituisce true mentre l'oggetto adiacente è modificato. Un transcript Linux x86-64 riuscito deve essere conservato prima di descrivere quel risultato come prova osservata.
f1-exploit fornisce il proprio layout della vittima, quindi non può rispondere se un processo non modificato abbia quel layout. finding01_groom usa glibc standard, PIE predefinito e ASLR, con hook globali di allocazione che registrano ma non riposizionano le allocazioni. Nei test conservati:
finding01 semplice muore allo stesso modo senza alcuna strumentazione.Sulla build glibc testata, il reperto 1 ha causato in modo affidabile denial of service; non è stato trovato alcun percorso di esecuzione di codice. La geometria testata era fissa, e altri allocatori o piattaforme possono disporre l'heap diversamente.
finding03_leak è il risultato più forte. Nella build testata, la lettura fuori limite raggiunge 131070 byte, un puntatore a vtable di gdcm::ByteValue entra nei pixel decodificati, e l'harness deriva la base di caricamento della libreria usando l'offset di vtable noto di quella build. Questo è un risultato locale di divulgazione a livello di API: richiede l'applicazione della LUT e l'accesso al buffer dei pixel decodificati. Non dimostra che un servizio di rete restituisca quei pixel.
I due non possono essere concatenati in esecuzione di codice qui, e non solo perché non è stata trovata alcuna vittima: richiedono valori diversi di PhotometricInterpretation, quindi richiedono due file, e una base divulgata è utile solo finché il processo che la divulga è ancora vivo.
Un report di sanitizer prova l'evento dichiarato di memory-safety o comportamento indefinito nel processo e nella revisione testati. f1-exploit verifica il controllo dei byte e una sovrascrittura di puntatore a funzione adiacente sotto un allocatore strumentato che fornisce deliberatamente il layout target. Non stabilisce quel layout in un consumatore non modificato. Le prove conservate di finding01_groom non hanno osservato quel layout per la geometria testata e la build glibc.
Niente di tutto ciò prova la raggiungibilità remota in un particolare prodotto, la persistenza o l'applicabilità a valle. L'argomento di raggiungibilità per un dato deployment è un'affermazione separata, fatta nel testo di divulgazione e non da questo pacchetto.