fix(wifi): prevent premature initIvars bypass of super::init and step down to step 2
- Breakthroughs & Rétro-ingénierie :
* Découverte critique dans IO80211SkywalkInterface::init (0xffffff80022f56e2) :
L'instruction cmpq $0x0, 0x120(%r14) suivie de jne 0x5733 saute l'appel super::init(0)
(IOService::init) si ivars est déjà non-nul.
* L'appel prématuré à initIvars dans createSkywalkInterface laissait donc la classe de base
IOService non initialisée (fPropertyTable = NULL).
* Lors de setInterfaceRole(1), setPropertyHelper appelait setProperty sur une table nulle,
provoquant le bootloop observé au stade 5.
- Modifications apportées :
* QualcommWifi/QualcommWifi.cpp :
- Retrait de l'appel à initIvars dans createSkywalkInterface pour laisser 0x120 à NULL
et garantir l'exécution de super::init(0) par IO80211SkywalkInterface::init.
- Calibrage du palier par défaut skywalk_step à 2 pour isoler la validation de init().
* docs/ISSUES_AND_POSTMORTEMS.md : Ajout du rapport post-mortem complet INC-17.
- Validation :
* Compilation build_wifi.sh réussie à 100%.
* kmutil libraries validé sans erreur contre BootKernelExtensions.kc.
This commit is contained in:
1 parent
79d772636f
commit
0519af4666
2 files changed
+39
-5
No files matched your search
@@ -144,7 +144,6 @@ static IO80211SkywalkInterface* createSkywalkInterface(void) {
|
||||
}
|
||||
bzero(mem, 0x128);
|
||||
_ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass(mem, &_ZN23IO80211SkywalkInterface10gMetaClassE);
|
||||
_ZN23IO80211SkywalkInterface9initIvarsEv(mem);
|
||||
return (IO80211SkywalkInterface *)mem;
|
||||
}
|
||||
|
||||
@@ -783,15 +782,15 @@ 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: 5 = attachement IORegistry complet)
|
||||
// 1: createSkywalkInterface (allocation + initIvars)
|
||||
// 2: init(this, &mac)
|
||||
// Étape maximale Skywalk contrôlée par boot-arg "qcom_step" (par défaut: 2 = init complet avec super::init)
|
||||
// 1: createSkywalkInterface (allocation)
|
||||
// 2: init(this, &mac) (super::init(0) + initIvars + copy 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 = 5;
|
||||
int skywalk_step = 2;
|
||||
PE_parse_boot_argn("qcom_step", &skywalk_step, sizeof(skywalk_step));
|
||||
|
||||
if (allow_skywalk) {
|
||||
|
||||
@@ -24,6 +24,7 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage
|
||||
| **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** |
|
||||
| **INC-16** | Bootloop par démarrage complet Skywalk & Piège de libération `free()` | Skywalk Lifecycle & Ivars Guard | Exécution aveugle du stade 6 (`start`), `#PF` CR2:0xb8 si `free()` sans `initIvars`, et `stop` non-gardé | **Résolu** |
|
||||
| **INC-17** | Page Fault sur table de propriétés NULL par court-circuit de `super::init(0)` | Skywalk Init Architecture | `initIvars` prématuré faisait croire à `init()` que `super::init(0)` avait déjà eu lieu | **Résolu** |
|
||||
|
||||
---
|
||||
|
||||
@@ -430,4 +431,38 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage
|
||||
4. **Validation intégrale de la chaîne de compilation** :
|
||||
- `build_wifi.sh` validé à 100% avec `kmutil libraries` auprès de `BootKernelExtensions.kc`.
|
||||
|
||||
---
|
||||
|
||||
### INC-17 : Page Fault sur Table de Propriétés NULL par Court-Circuit de `super::init(0)`
|
||||
* **Symptômes** :
|
||||
- Bootloop lors du passage au stade 5 (commit `79d7726`), alors que le stade 1 (commit `b7e32db`) démarrait impeccablement jusqu'au bureau macOS.
|
||||
* **Causes Racines (Breakthroughs & Rétro-ingénierie du Kernel Collection)** :
|
||||
1. **Analyse de la condition d'initialisation dans `IO80211SkywalkInterface::init` (`0xffffff80022f56e2`)** :
|
||||
- Le désassemblage précis montre la logique suivante :
|
||||
```assembly
|
||||
0xffffff80022f5710: cmpq $0x0, 0x120(%r14) ; ivars est-il NULL ?
|
||||
0xffffff80022f5718: jne 0xffffff80022f5733 ; Si NON-NULL, SAUTE super::init(0) !
|
||||
0xffffff80022f571a: movq 0x15aa07(%rip), %rax ; __ZTV26IOSkywalkEthernetInterface
|
||||
0xffffff80022f5724: movq %r14, %rdi
|
||||
0xffffff80022f5729: callq *0x258(%rax) ; super::init(0) -> IOService::init()
|
||||
0xffffff80022f5733: movq %r14, %rdi
|
||||
0xffffff80022f5736: callq initIvars ; initIvars()
|
||||
```
|
||||
- Dans le commit `b7e32db`/`79d7726`, nous appelions `initIvars` dès `createSkywalkInterface()` pour éviter le piège de `free()`.
|
||||
- Par conséquent, lors de l'appel à `fSkywalkInterface->init(...)`, `mem + 0x120` était **déjà non-nul** !
|
||||
- Le saut conditionnel `jne 0x5733` a donc été emprunté, **court-circuitant totalement l'appel `super::init(0)` (`IOService::init()`)** !
|
||||
2. **Conséquence fatale sur `IOService` et les tables de propriétés** :
|
||||
- Sans `IOService::init()`, l'infrastructure de base de l'objet (dictionnaire de propriétés `fPropertyTable`, table de registre IORegistry, verrous de synchronisation) n'était pas allouée.
|
||||
- Dès l'étape suivante (`setInterfaceRole(1)`), le noyau exécutait `setPropertyHelper(this, "IO80211InterfaceRole", ...)` qui tente d'écrire dans la table de propriétés NULL de l'objet, déclenchant un Kernel Page Fault instantané !
|
||||
* **Résolutions Techniques Appliquées** :
|
||||
1. **Suppression de l'appel prématuré à `initIvars` dans `createSkywalkInterface`** :
|
||||
- `createSkywalkInterface` ne fait plus que `operator new` + mise à zéro explicite (`bzero(0x128)`) + constructeur C1.
|
||||
- `mem + 0x120` reste strictement NULL.
|
||||
- `fSkywalkInterface->init(...)` constate `0x120 == 0`, invoque légitimement `super::init(0)` pour initialiser `IOService`, puis invoque `initIvars()`.
|
||||
- L'objet est alors 100% cohérent à la fois côté `IOService` et côté `IO80211SkywalkInterface`.
|
||||
2. **Calibrage sécurisé du palier par défaut sur l'étape 2 (`skywalk_step=2`)** :
|
||||
- Permet de valider isolément que `createSkywalkInterface` + `init(this, mac)` démarre avec succès sans risque d'effets de bord ultérieurs.
|
||||
3. **Validation binaire et dépendances** :
|
||||
- Compilation `build_wifi.sh` et validation `kmutil libraries` à 100%.
|
||||
|
||||
|
||||
Reference in new issue
Block a user