fix(wifi): resolve INC-15 uninitialized heap trap in initIvars and correct Skywalk attachment sequence
### Breakthroughs & Rétro-ingénierie - **Piège du tas non initialisé (Uninitialized Heap Trap) dans initIvars (0xffffff80022f520c)** : - IO80211SkywalkInterfacenwEm(0x128) alloue la mémoire de l'objet via kalloc_type, sans initialisation à zéro. - Dans initIvars, le noyau teste si [rdi + 0x120] est nul. En présence de résidus du tas non nuls, le noyau dérive vers le bloc movq 0x120(%rbx), %rdi; callq memset(garbage, 0, 0xf0), déclenchant un Kernel Page Fault (#PF) / Triple Fault instantané. - Résolution : bzero(mem, 0x128); systématique avant invocation du constructeur. - **Header erroné network/IOSkywalkEthernetInterface.h** : - Correction de l'héritage fictif d'IOEthernetController vers la hiérarchie Skywalk conforme : IOService -> IOSkywalkInterface -> IOSkywalkNetworkInterface -> IOSkywalkEthernetInterface. - **Ordre d'attachement Skywalk & contrôleur (Slot 441)** : - Broadcom (AppleBCMWLANCore::createSkywalkInterface) appelle attachInterface(fSkywalkInterface, this) au slot 441 avant fSkywalkInterface->attach(this) et start(this), avec this en second paramètre pour renseigner controller->ivars + 0x188 (fPrimaryInterface). - **Suppression de registerService() prématuré** : - Gated derrière qcom_step >= 7 (défaut: 6 = exécution complète de start(this) sans enregistrement prématuré déclenchant le matching IOKit sans buffers). ### Modifications apportées - QualcommWifi/QualcommWifi.cpp : - Ajout de bzero(mem, 0x128) après l'allocation de IO80211SkywalkInterface. - Réordonnancement de l'attachement : appel de slot 441 attachInterface(fSkywalkInterface, this) avant attach(this) et start(this). - Contrôle d'exécution granulaire par palier via le boot-arg qcom_step (défaut: 6). - QualcommWireless/include/IOKit/network/IOSkywalkEthernetInterface.h : - Redirection propre vers <IOKit/skywalk/IOSkywalkEthernetInterface.h>. - QualcommWireless/include/IOKit/skywalk/IOSkywalkTypes.h : - Ajout du typedef manquant uint32_t kern_packet_svc_class_t. - docs/ISSUES_AND_POSTMORTEMS.md : - Documentation exhaustive du post-mortem INC-15. ### Validation - Compilation réussie via ./build_wifi.sh. - Validation des bibliothèques et symboles kmutil libraries -p réussie à 100% contre BootKernelExtensions.kc.
This commit is contained in:
1 parent
c401f7f90c
commit
506df09b68
5 files changed
+113
-35
No files matched your search
@@ -141,10 +141,12 @@ static IO80211SkywalkInterface* createSkywalkInterface(void) {
|
||||
IOLog("QualcommWifi: Erreur - operator new(IO80211SkywalkInterface) a echoue !\n");
|
||||
return nullptr;
|
||||
}
|
||||
bzero(mem, 0x128);
|
||||
_ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass(mem, &_ZN23IO80211SkywalkInterface10gMetaClassE);
|
||||
return (IO80211SkywalkInterface *)mem;
|
||||
}
|
||||
|
||||
|
||||
#define super IO80211Controller
|
||||
OSDefineMetaClassAndStructors(QualcommWifi, IO80211Controller)
|
||||
|
||||
@@ -776,42 +778,74 @@ bool QualcommWifi::start(IOService *provider) {
|
||||
int allow_skywalk = 1;
|
||||
PE_parse_boot_argn("qcom_skywalk", &allow_skywalk, sizeof(allow_skywalk));
|
||||
|
||||
// Étape maximale Skywalk contrôlée par boot-arg "qcom_step" (par défaut: 6 = jusqu'à start(this))
|
||||
// 1: createSkywalkInterface
|
||||
// 2: init(this, &mac)
|
||||
// 3: setInterfaceRole(1)
|
||||
// 4: attachInterface(fSkywalkInterface, this) [slot 441 sur controller]
|
||||
// 5: fSkywalkInterface->attach(this) [attachement IORegistry]
|
||||
// 6: fSkywalkInterface->start(this) [démarrage Skywalk, joinPMtree, workQueue, etc.]
|
||||
// 7: fSkywalkInterface->registerService() [matching IOKit / airportd]
|
||||
int skywalk_step = 6;
|
||||
PE_parse_boot_argn("qcom_step", &skywalk_step, sizeof(skywalk_step));
|
||||
|
||||
if (allow_skywalk) {
|
||||
logNvramStage("skywalk_alloc");
|
||||
fSkywalkInterface = createSkywalkInterface();
|
||||
if (fSkywalkInterface) {
|
||||
logNvramStage("skywalk_init");
|
||||
if (fSkywalkInterface->init(this, (ether_addr *)&fMacAddress)) {
|
||||
logNvramStage("skywalk_role");
|
||||
fSkywalkInterface->setInterfaceRole(1); // 1 = kIO80211InterfaceRoleInfra (Primary Wi-Fi)
|
||||
logNvramStage("skywalk_attach");
|
||||
if (fSkywalkInterface->attach(this)) {
|
||||
logNvramStage("skywalk_start");
|
||||
if (fSkywalkInterface->start(this)) {
|
||||
IOLog("QualcommWifi: createSkywalkInterface réussi (0x%p) !\n", fSkywalkInterface);
|
||||
if (skywalk_step >= 2) {
|
||||
logNvramStage("skywalk_init");
|
||||
if (fSkywalkInterface->init(this, (ether_addr *)&fMacAddress)) {
|
||||
IOLog("QualcommWifi: fSkywalkInterface->init(...) réussi !\n");
|
||||
if (skywalk_step >= 3) {
|
||||
logNvramStage("skywalk_role");
|
||||
fSkywalkInterface->setInterfaceRole(1); // 1 = kIO80211InterfaceRoleInfra (Primary Wi-Fi)
|
||||
IOLog("QualcommWifi: fSkywalkInterface->setInterfaceRole(1) configuré !\n");
|
||||
}
|
||||
if (skywalk_step >= 4) {
|
||||
logNvramStage("skywalk_attach_ctrl");
|
||||
attachInterface(fSkywalkInterface, nullptr); // slot 441 in IO80211Controller
|
||||
logNvramStage("skywalk_register");
|
||||
fSkywalkInterface->registerService();
|
||||
IOLog("QualcommWifi: Interface Skywalk native (IO80211SkywalkInterface) attachée et enregistrée avec succès !\n");
|
||||
} else {
|
||||
logNvramStage("skywalk_start_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->start(this) a échoué !\n");
|
||||
fSkywalkInterface->detach(this);
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
bool ctrlAttachOk = attachInterface(fSkywalkInterface, this); // slot 441 in IO80211Controller
|
||||
IOLog("QualcommWifi: this->attachInterface(fSkywalkInterface, this) = %d\n", ctrlAttachOk);
|
||||
}
|
||||
if (skywalk_step >= 5) {
|
||||
logNvramStage("skywalk_attach");
|
||||
if (fSkywalkInterface->attach(this)) {
|
||||
IOLog("QualcommWifi: fSkywalkInterface->attach(this) réussi !\n");
|
||||
if (skywalk_step >= 6) {
|
||||
logNvramStage("skywalk_start");
|
||||
if (fSkywalkInterface->start(this)) {
|
||||
IOLog("QualcommWifi: fSkywalkInterface->start(this) démarré avec succès !\n");
|
||||
if (skywalk_step >= 7) {
|
||||
logNvramStage("skywalk_register");
|
||||
fSkywalkInterface->registerService();
|
||||
IOLog("QualcommWifi: fSkywalkInterface->registerService() publié !\n");
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_start_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->start(this) a échoué !\n");
|
||||
fSkywalkInterface->detach(this);
|
||||
detachInterface(fSkywalkInterface, false);
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_attach_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->attach(this) a échoué !\n");
|
||||
detachInterface(fSkywalkInterface, false);
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_attach_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->attach(this) a échoué !\n");
|
||||
logNvramStage("skywalk_init_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->init(...) a échoué !\n");
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_init_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->init(...) a échoué !\n");
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int allow_register = 0;
|
||||
PE_parse_boot_argn("qcom_register", &allow_register, sizeof(allow_register));
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
#ifndef _IO80211SKYWALK_H
|
||||
#define _IO80211SKYWALK_H
|
||||
|
||||
#include <Availability.h>
|
||||
#include <IOKit/network/IOSkywalkEthernetInterface.h>
|
||||
#include <IOKit/skywalk/IOSkywalkEthernetInterface.h>
|
||||
|
||||
// This is necessary, because even the latest Xcode does not support properly targeting 11.0.
|
||||
#ifndef __IO80211_TARGET
|
||||
|
||||
@@ -6,16 +6,10 @@
|
||||
// Copyright © 2019 钟先耀. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _IOSKYWALKINTERFACE_H
|
||||
#define _IOSKYWALKINTERFACE_H
|
||||
#ifndef _IOKIT_NETWORK_IOSKYWALKETHERNETINTERFACE_H
|
||||
#define _IOKIT_NETWORK_IOSKYWALKETHERNETINTERFACE_H
|
||||
|
||||
#include <IOKit/network/IOEthernetController.h>
|
||||
#include <IOKit/skywalk/IOSkywalkEthernetInterface.h>
|
||||
|
||||
class IOSkywalkEthernetInterface : public IOEthernetController {
|
||||
OSDeclareAbstractStructors( IOSkywalkEthernetInterface )
|
||||
#endif /* _IOKIT_NETWORK_IOSKYWALKETHERNETINTERFACE_H */
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
#endif /* _IOSKYWALKINTERFACE_H */
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include <IOKit/IOLib.h>
|
||||
|
||||
typedef uint32_t kern_packet_svc_class_t;
|
||||
|
||||
typedef uint32_t IOSkywalkNetworkLinkStatus;
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -20,6 +20,9 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage
|
||||
| **INC-10** | Triple Fault Processeur ("Coupure de Courant") | Logger / CoreCapture | Déréférencement de `+0x90 -> +0x58` dans `CCLogStream::shouldLog` | **Résolu** |
|
||||
| **INC-11** | Freeze Apple Logo (non-verbose) / Triple Fault (verbose) | NVRAM & Matching IOKit | Matching prématuré de `registerService()` & heap dynamique précoce | **Résolu** |
|
||||
| **INC-12** | **Triple Fault / Freeze Apple Logo persistant** | `FakeLogStream` / `FakeFaultReporter` | Vtables tronquées à 38 slots (au lieu de 283/269) & `0x88->0x48` Page 0 `#PF` dans `logv` | **Résolu** |
|
||||
| **INC-13** | Page Fault `CR2: 0x658` dans `ml_thread_policy` au boot | `IOWorkLoop` vs `IO80211WorkQueue` | `IO80211WorkQueue::getThread()` retourne 0, deref `thread->mutex` (+0x658) | **Résolu** |
|
||||
| **INC-14** | Page Fault `CR2: 0x1` dans `printDataPath` | `IO80211SkywalkInterface.h` | Méthodes `init` et `setInterfaceRole` déclarées `virtual` par erreur | **Résolu** |
|
||||
| **INC-15** | Kernel Trap / Triple Fault dans `initIvars` & `attachInterface` | Skywalk Heap & Attachment ABI | Tas non initialisé (`bzero` manquant), header incorrect, ordre d'attachement et `registerService` prématuré | **Résolu** |
|
||||
|
||||
---
|
||||
|
||||
@@ -352,3 +355,49 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage
|
||||
3. **Conformité des Dépendances** :
|
||||
- `kmutil libraries -p build/Release/QualcommWifi.kext` valide la résolution intégrale des symboles auprès de `BootKernelExtensions.kc`.
|
||||
|
||||
---
|
||||
|
||||
### INC-15 : Kernel Trap / Triple Fault dans `initIvars` & Incohérence d'Attachement Skywalk
|
||||
* **Symptômes** :
|
||||
- Bootloop persistant et redémarrage brutal de la machine lors de la phase d'instanciation de `IO80211SkywalkInterface`.
|
||||
- Machine incapable de franchir le stade d'attachement réseau natif sans désactivation manuelle de `QualcommWifi.kext` dans OpenCore.
|
||||
* **Causes Racines (Breakthroughs & Rétro-ingénierie du Kernel Collection)** :
|
||||
1. **Piège du tas non initialisé (Uninitialized Heap Trap) dans `initIvars` (`0xffffff80022f520c`)** :
|
||||
- `_ZN23IO80211SkywalkInterfacenwEm(0x128)` alloue la mémoire de l'objet via `kalloc_type`. Le noyau **ne met pas la mémoire à zéro**.
|
||||
- Dans le constructeur et dans `IO80211SkywalkInterface::initIvars`, le noyau évalue :
|
||||
```assembly
|
||||
0xffffff80022f5215: cmpq $0x0, 0x120(%rdi)
|
||||
0xffffff80022f521d: je 0xffffff80022f5265 ; Alloue ivars si NULL
|
||||
...
|
||||
0xffffff80022f5244: movq 0x120(%rbx), %rdi ; Garbage pointer !
|
||||
0xffffff80022f524b: movl $0xf0, %esi
|
||||
0xffffff80022f5250: movl $0xf0, %ecx
|
||||
0xffffff80022f5255: xorl %edx, %edx
|
||||
0xffffff80022f5257: callq memset ; memset(garbage, 0, 0xf0) -> Page Fault Ring 0 !
|
||||
```
|
||||
- Si `mem + 0x120` contient des résidus non nuls de la mémoire du tas, le noyau tente un `memset` de `0xf0` octets sur cette adresse invalide, causant un Crash Kernel Page Fault / Triple Fault instantané.
|
||||
2. **Header erroné `network/IOSkywalkEthernetInterface.h`** :
|
||||
- Le fichier `QualcommWireless/include/IOKit/network/IOSkywalkEthernetInterface.h` déclarait de manière erronée `class IOSkywalkEthernetInterface : public IOEthernetController`.
|
||||
- Dans l'architecture Apple Skywalk, `IOSkywalkEthernetInterface` hérite en réalité de `IOSkywalkNetworkInterface` -> `IOSkywalkInterface` -> `IOService`, sans aucun lien d'héritage avec `IOEthernetController`.
|
||||
3. **Ordre d'attachement et second argument du contrôleur (Slot 441)** :
|
||||
- Dans `AppleBCMWLANCore::createSkywalkInterface` (`0xffffff80016aaa8a`), Apple invoque `this->attachInterface(fSkywalkInterface, this)` (slot 441 d'`IO80211Controller`) **avant** `fSkywalkInterface->attach(this)` et `fSkywalkInterface->start(this)`.
|
||||
- De plus, le second paramètre transmis doit être `this` (le contrôleur), ce qui renseigne `controller->ivars + 0x188` (`fPrimaryInterface`). L'ancien code passait `nullptr` après `start()`.
|
||||
4. **Publication prématurée via `registerService()`** :
|
||||
- Appeler `registerService()` sur `fSkywalkInterface` publie le service auprès du système IOKit matching et d'`airportd` avant que les queues Skywalk et les pools de buffers ne soient négociés, provoquant une panique réseau immédiate.
|
||||
* **Résolutions Techniques Appliquées** :
|
||||
1. **Remise à zéro explicite du bloc mémoire avant construction** :
|
||||
```cpp
|
||||
void *mem = _ZN23IO80211SkywalkInterfacenwEm(0x128);
|
||||
if (!mem) return nullptr;
|
||||
bzero(mem, 0x128);
|
||||
_ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass(mem, &_ZN23IO80211SkywalkInterface10gMetaClassE);
|
||||
```
|
||||
2. **Correction des inclusions d'en-têtes Skywalk** :
|
||||
- Redirection du faux header vers `<IOKit/skywalk/IOSkywalkEthernetInterface.h>` et ajout du `typedef uint32_t kern_packet_svc_class_t;` dans `IOSkywalkTypes.h`.
|
||||
3. **Ordonnancement conforme du cycle d'attachement Skywalk** :
|
||||
- Invocation de `attachInterface(fSkywalkInterface, this)` au slot 441 avant `attach(this)` et `start(this)`.
|
||||
4. **Contrôle granulaire d'exécution par palier via le boot-arg `qcom_step`** :
|
||||
- Introduction du palier `qcom_step` (par défaut `6` = exécution complète de `start(this)` sans appeler prématurément `registerService()`).
|
||||
- Validation binaire par désassemblage et validation `kmutil libraries` à 100%.
|
||||
|
||||
|
||||
Reference in new issue
Block a user