From 6017b35300eca87d03fbf42af357120b7f27b0c1 Mon Sep 17 00:00:00 2001 From: Erwan Date: Mon, 19 Oct 2026 00:34:58 +0200 Subject: [PATCH] feat(wifi): blinder getPrimarySkywalkInterface, setMulticastList et armer le Stade 6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Breakthroughs & Rétro-ingénierie : * Audit binaire exhaustif par désassemblage Capstone des 2,5 Mo du segment IO80211Family dans BootKernelExtensions.kc : identification de 38 slots de vtable invoqués. * Découverte critique sur slot 400 (0xc80, getPrimarySkywalkInterface) appelé 99 fois dans IO80211Family : l'appelant déréférence directement ivars (mov rax, [rax + 0x120]) sans vérifier la nullité du pointeur. Si le contrôleur renvoie NULL, un Kernel Page Fault instantané survient (CR2: 0x120). * Blindage proactif par surcharge explicite de getPrimarySkywalkInterface() retournant directement fSkywalkInterface. * Sécurisation du slot 462 (0xe70, setMulticastList) par stub renvoyant kIOReturnSuccess pour immuniser contre toute requête multicast non gérée de la pile réseau BSD. * Validation de la stratégie d'amorçage : maintien de l'isolation logicielle (qcom_mmio=0) pour valider la stabilité de Skywalk avant l'engagement du SoC physique WCN7850. - Modifications apportées : * QualcommWifi/QualcommWifi.hpp : déclaration des surcharges getPrimarySkywalkInterface() et setMulticastList(). * QualcommWifi/QualcommWifi.cpp : implémentation avec télémétrie NVRAM (cb_getPrimarySkywalk, cb_setMulticast). * docs/ISSUES_AND_POSTMORTEMS.md : rédaction du Postmortem 17 détaillant l'audit binaire et les 38 slots de vtable. * EFI OpenCore : déploiement de QualcommWifi.kext dans /Volumes/EFI/EFI/OC/Kexts/ et configuration des boot-args sur qcom_step=6 qcom_substep=1 dans config.plist. - Validation : * Compilation sans aucun avertissement via ./build_wifi.sh. * kmutil libraries -p build/Release/QualcommWifi.kext validé à 100% contre BootKernelExtensions.kc. * Déploiement vérifié sur /Volumes/EFI/EFI/OC/. --- QualcommWifi/QualcommWifi.cpp | 10 ++++++++ QualcommWifi/QualcommWifi.hpp | 2 ++ docs/ISSUES_AND_POSTMORTEMS.md | 45 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/QualcommWifi/QualcommWifi.cpp b/QualcommWifi/QualcommWifi.cpp index 1401092..bc480eb 100644 --- a/QualcommWifi/QualcommWifi.cpp +++ b/QualcommWifi/QualcommWifi.cpp @@ -1084,6 +1084,16 @@ UInt32 QualcommWifi::getActionFramePoolCapacity(void) { return 0x100; } +IO80211SkywalkInterface* QualcommWifi::getPrimarySkywalkInterface(void) { + logNvramStage("cb_getPrimarySkywalk"); + return fSkywalkInterface; +} + +IOReturn QualcommWifi::setMulticastList(ether_addr const *addrs, UInt32 count) { + logNvramStage("cb_setMulticast"); + return kIOReturnSuccess; +} + IOReturn QualcommWifi::getDRIVER_VERSION(IO80211SkywalkInterface *iface, apple80211_version_data *vd) { return (IOReturn)handleApple80211Request(APPLE80211_IOC_DRIVER_VERSION, 0, vd); } diff --git a/QualcommWifi/QualcommWifi.hpp b/QualcommWifi/QualcommWifi.hpp index 1287c06..5b386ee 100644 --- a/QualcommWifi/QualcommWifi.hpp +++ b/QualcommWifi/QualcommWifi.hpp @@ -267,6 +267,8 @@ public: virtual void* getFaultReporterFromDriver(void) override; virtual IORecursiveLock* allocIO80211RecursiveLock(void) override; virtual UInt32 getActionFramePoolCapacity(void) override; + virtual IO80211SkywalkInterface* getPrimarySkywalkInterface(void) override; + virtual IOReturn setMulticastList(ether_addr const *addrs, UInt32 count) override; // Dispatcher de requêtes Apple80211 / airportd SInt32 handleApple80211Request(unsigned int req_type, int req_val, void* req_data); diff --git a/docs/ISSUES_AND_POSTMORTEMS.md b/docs/ISSUES_AND_POSTMORTEMS.md index fe794c9..1f1a92c 100644 --- a/docs/ISSUES_AND_POSTMORTEMS.md +++ b/docs/ISSUES_AND_POSTMORTEMS.md @@ -663,6 +663,51 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage 4. **Validation** : - Compilation réussie sans avertissement (`./build_wifi.sh`), validation `kmutil libraries` à 100% contre `BootKernelExtensions.kc`. +--- + +### Postmortem 17 : Audit Binaire Exhaustif des Callbacks Skywalk / airportd et Armement Sécurisé du Stade 6 + +* **Date** : 19 Octobre 2026 +* **Cible** : macOS Tahoe 26.x (Darwin 25.6.0 x86_64), AMD Ryzen 7 5800X3D, `QualcommWifi.kext` (WCN7850 `0x17cb:0x1107`) +* **Contexte & Démarche (/grill-me)** : + - Suite à l'éradication de la régression d'alias `IOWorkLoop` (Postmortem 16), un audit désassemblé systématique des interactions binaires entre `IO80211Family.kext` et le contrôleur `IO80211Controller` / `QualcommWifi` a été mené afin d'anticiper et de neutraliser tout déréférencement fatal ou point de blocage avant le démarrage matériel. +* **Breakthroughs & Rétro-ingénierie du Kernel Collection (`BootKernelExtensions.kc`)** : + 1. **Cartographie Complète des 38 Slots Virtuels Sollicités dans `IO80211Family`** : + - Le balayage automatique Capstone sur les 2,5 Mo du segment `IO80211Family` a recensé l'intégralité des 38 slots de méthodes virtuelles invoqués sur le contrôleur et l'interface : + * Slot 394 (`0xc50`) : `isCommandProhibited(int)` (1 appel) -> retourne `false`. + * Slot 397 (`0xc68`) : `getWorkQueue()` (47 appels) -> retourne `fWorkQueue`. + * Slot 399 (`0xc78`) : `getIO80211CommandGate()` (10 appels) -> instancié dans `super::start` (`ivars + 0x3c0`). + * **Slot 400 (`0xc80`) : `getPrimarySkywalkInterface()` (99 appels !)** : + - Révélation critique à l'adresse `0xffffff80021d9836` : + ```assembly + call [rax + 0xc80] ; controller->getPrimarySkywalkInterface() + mov rax, qword ptr [rax + 0x120] ; Déréférencement direct de ivars SANS test de nullité ! + ``` + - Si `getPrimarySkywalkInterface()` retourne `NULL`, le noyau subit un Kernel Page Fault instantané `CR2: 0x0000000000000120`. + - L'implémentation par défaut de `IO80211Controller` interroge `ivars + 0x188`. + - **Blindage** : Surcharge explicite de `getPrimarySkywalkInterface()` dans `QualcommWifi` renvoyant directement `fSkywalkInterface`. + * Slot 403 (`0xc98`) : `handleCardSpecific()` (5 appels) -> redirigé vers `handleApple80211Request`. + * Slot 404 (`0xca0`) : `hardwareOutputQueueDepth()` (2 appels) -> retourne 0. + * Slot 405 (`0xca8`) : `performCountryCodeOperation()` (2 appels) -> retourne 0. + * Slot 406 (`0xcb0`) : `dataLinkLayerAttachComplete()` -> accusé de réception journalisé NVRAM. + * Slot 424 (`0xd40`) : `getLogger()` (54 appels) -> retourne `fLogger` (conforme `FakeLogStream`). + * Slot 432 (`0xd80`) : `getFaultReporterFromDriver()` (1 appel) -> retourne `fFaultReporter` (conforme `FakeFaultReporter`). + * Slot 433 (`0xd88`) : `allocIO80211RecursiveLock()` (1 appel) -> allocation concrète du verrou récursif pour `IO80211PeerManager`. + * Slot 435 (`0xd98`) : `wasDynSARInFailSafeMode()` (1 appel) -> stub sécurisé renvoyant 0. + * Slot 438 (`0xdb0`) : `getActionFramePoolCapacity()` (2 appels) -> retourne `0x100`. + * **Slot 462 (`0xe70`) : `setMulticastList(ether_addr const*, UInt32)` (5 appels)** : + - Surcharge explicite ajoutée retournant `kIOReturnSuccess` pour sécuriser les requêtes multicast de la pile réseau BSD. + 2. **Stratégie d'Amorçage Validée : Isolation Logicielle (`qcom_mmio=0`) et Stade 6 (`qcom_step=6`)** : + - Démarrage en mode logiciel pur : pas d'accès direct MMIO/ASPM aux registres matériels du SoC WCN7850 afin de tester la chaîne Skywalk/airportd dans un environnement parfaitement déterministe. + - Configuration du boot-arg `qcom_substep=1` : pause de 10 secondes précédant l'appel `start(this)` pour observation visuelle sur console série/écran. +* **Modifications Apportées** : + 1. `QualcommWifi/QualcommWifi.hpp` : déclaration des surcharges `getPrimarySkywalkInterface()` et `setMulticastList()`. + 2. `QualcommWifi/QualcommWifi.cpp` : implémentation avec journalisation NVRAM (`cb_getPrimarySkywalk`, `cb_setMulticast`). + 3. Déploiement : + - Recompilation avec `./build_wifi.sh` (validation `kmutil libraries` 100%). + - Déploiement vers `/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext`. + - Mise à jour du `boot-args` OpenCore dans `/Volumes/EFI/EFI/OC/config.plist` : `qcom_step=6 qcom_substep=1`. +