
Analyse des causes profondes et exploit fonctionnel pour CVE-2026-78938, une confusion de types V8 TurboFan conduisant à une lecture/écriture arbitraire dans le tas compressé. Inclut un PoC de crash et des primitives adressées au moment de l'exécution.
Analyse de cause racine et exploit pour CVE-2026-78938, une confusion de type dans l'élimination de charges de TurboFan de V8, corrigée dans Chrome 152.0.7977.64 (V8 15.2.124.18). Le bug a été signalé comme exploité dans la nature.
L'exploit transforme le bug en un Float64Array hors limites, puis en
addrof / fakeobj et en lecture/écriture arbitraire sur le tas compressé de V8.
Tout ce qui suit l'écriture initiale est localisé à l'exécution — il n'y a
aucun décalage de tas codé en dur dans l'étape L/E.
50597b0bb48a — "[compiler] Invalidate tracked fields on
CheckMaps with instance migration"Testé sur macOS arm64 avec un d8 compilé localement pour les deux versions.
| fichier | description |
|---|
pocs/crash.js | Déclencheur minimal. SIGBUS sur la build vulnérable, sortie propre sur la build corrigée. |
pocs/rw_final.js | Exploit complet, étape 1 : déclencheur + tableau OOB. Figé — voir « Reproduction » ci-dessous. |
pocs/logic_final.js | Exploit complet, étape 2 : addrof/fakeobj/L\E arbitraire, chargé à l'exécution par l'étape 1. |
WRITEUP.md | Analyse complète de la cause racine et notes d'exploitation. |
Compilez les deux versions de d8 (voir WRITEUP.md pour les commits exacts et
les arguments GN), puis depuis la racine du dépôt :
# PoC de crash : SIGBUS sur vuln, sortie propre sur patched
out/vuln/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/crash.js
out/patched/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/crash.js
# L/E complète : fonctionne sur vuln, abandon propre sur patched
out/vuln/d8 --allow-natives-syntax --homomorphic-ic --max-valid-polymorphic-map-count=4 pocs/rw_final.js
Sortie attendue sur la build vulnérable :
[+] OOB Float64Array len=0x7f000004
[+] after write: victim2.z = 2.5
[+] fakeobj(hn|1) typeof=number
[+] ALL PRIMITIVES VERIFIED
Deux points importants :
--homomorphic-ic --max-valid-polymorphic-map-count=4 façonnent le retour polymorphique des
maps afin que le chemin de migration soit emprunté dans le code optimisé.
Sans eux, le déclencheur ne fait silencieusement rien.pocs/rw_final.js est figé octet par octet. La seule écriture
corruptrice atterrit à un décalage relatif au tas qui dépend de l'endroit où
le tableau victime est alloué, ce qui dépend à son tour des octets exacts et
du chemin du script. Modifier le fichier (ou le renommer) invalide le
décalage intégré ; WRITEUP.md documente comment le ré-étalonner.
pocs/logic_final.js est chargé après que le déclencheur se soit produit,
il peut donc être modifié librement.pocs/rw_final.js,
pour les raisons évoquées ci-dessus.Ce dépôt est destiné à des fins de recherche pédagogique et défensive. Le bug est corrigé dans Chrome actuel ; les détails sont publics dans l'arborescence source de V8.