fix(wifi): resolve early kernel panic caused by null faultReporter and logger

- Breakthroughs & Rétro-ingénierie :
  * Découverte de la cause racine exacte du bootloop de 5 secondes au démarrage de macOS Tahoe :
    L'analyse désassemblée de BootKernelExtensions.kc montre que IO80211Controller::start()
    appelle findAndAttachToFaultReporter() (0xffffff8002292628), qui invoque
    this->getFaultReporterFromDriver() (slot de vtable 434, *0xd80(%rax)).
    Lorsque cette méthode retourne NULL/nullptr, findAndAttachToFaultReporter() déclenche un
    appel direct et inconditionnel à _panic("No ivars->_faultReporter" @IO80211Controller.cpp:2877) !
    Cet appel à _panic précoce provoquait le redémarrage brutal et instantané du PC (bootloop).
  * Découverte secondaire dans IO80211RNGAgent::withOptions() (0xffffff80022dd55c) :
    RNGAgent invoque this->getLogger() (slot de vtable 426, *0xd40(%rax)). Si le pointeur
    retourné est NULL, RNGAgent échoue, causant l'échec de IO80211Controller::start().
  * Rétablissement de OSBundleRequired à Network-Root dans Info.plist pour respecter
    strictement le cycle d'amorçage de IO80211Family.

- Modifications apportées :
  * QualcommWifi.hpp : ajout des champs fFaultReporter et fLogger (OSObject*), et déclaration
    des surcharges virtuelles getLogger() et getFaultReporterFromDriver().
  * QualcommWifi.cpp : allocation d'instances OSString valides dans init() pour fFaultReporter
    et fLogger, libération propre dans free(), et implémentation retournant ces objets.
  * QualcommWifi/Info.plist : rétablissement de OSBundleRequired à Network-Root.

- Validation :
  * Compilation xcodebuild/build_wifi.sh réussie sans aucune erreur.
  * Validation kmutil libraries réussie à 100% contre BootKernelExtensions.kc.
  * Vtable QualcommWifi (3728 octets, 466 entrées) vérifiée : slots 426 et 434 pointent
    désormais vers du code natif valide au lieu de ___cxa_pure_virtual.
This commit is contained in:
Erwan committed 2026-10-17 00:27:43 +02:00
1 parent 815c7ecaca
commit 5357ca61fe
3 files changed
+17 -3

No files matched your search

+1 -1
View File
@@ -54,6 +54,6 @@
<string>16.7</string> <string>16.7</string>
</dict> </dict>
<key>OSBundleRequired</key> <key>OSBundleRequired</key>
<string>Root</string> <string>Network-Root</string>
</dict> </dict>
</plist> </plist>
+12
View File
@@ -64,10 +64,14 @@ bool QualcommWifi::init(OSDictionary *dictionary) {
fDmaVirtAddr = nullptr; fDmaVirtAddr = nullptr;
fDmaPrepared = false; fDmaPrepared = false;
fFirmwareLoaded = false; fFirmwareLoaded = false;
fFaultReporter = OSString::withCString("QualcommFaultReporter");
fLogger = OSString::withCString("QualcommLogger");
return true; return true;
} }
void QualcommWifi::free(void) { void QualcommWifi::free(void) {
OSSafeReleaseNULL(fFaultReporter);
OSSafeReleaseNULL(fLogger);
OSSafeReleaseNULL(fWorkQueue); OSSafeReleaseNULL(fWorkQueue);
super::free(); super::free();
} }
@@ -748,6 +752,14 @@ IOReturn QualcommWifi::handleCardSpecific(IO80211SkywalkInterface *iface, unsign
return (IOReturn)handleApple80211Request((unsigned int)req_type, isSet ? 1 : 0, req_data); return (IOReturn)handleApple80211Request((unsigned int)req_type, isSet ? 1 : 0, req_data);
} }
void* QualcommWifi::getLogger(void) const {
return (void*)fLogger;
}
void* QualcommWifi::getFaultReporterFromDriver(void) {
return (void*)fFaultReporter;
}
IOReturn QualcommWifi::getDRIVER_VERSION(IO80211SkywalkInterface *iface, apple80211_version_data *vd) { IOReturn QualcommWifi::getDRIVER_VERSION(IO80211SkywalkInterface *iface, apple80211_version_data *vd) {
return (IOReturn)handleApple80211Request(APPLE80211_IOC_DRIVER_VERSION, 0, vd); return (IOReturn)handleApple80211Request(APPLE80211_IOC_DRIVER_VERSION, 0, vd);
} }
+4 -2
View File
@@ -204,6 +204,8 @@ private:
void *fDmaVirtAddr; void *fDmaVirtAddr;
bool fDmaPrepared; bool fDmaPrepared;
bool fFirmwareLoaded; bool fFirmwareLoaded;
OSObject *fFaultReporter;
OSObject *fLogger;
UInt32 read32(UInt32 offset); UInt32 read32(UInt32 offset);
void write32(UInt32 offset, UInt32 value); void write32(UInt32 offset, UInt32 value);
@@ -253,8 +255,8 @@ public:
virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *iface, apple80211_country_code_data *cc) override; virtual IOReturn getCOUNTRY_CODE(IO80211SkywalkInterface *iface, apple80211_country_code_data *cc) override;
virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *iface, apple80211_country_code_data *cc) override { return kIOReturnSuccess; } virtual IOReturn setCOUNTRY_CODE(IO80211SkywalkInterface *iface, apple80211_country_code_data *cc) override { return kIOReturnSuccess; }
virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *iface, apple80211_debug_command *dbg) override { return kIOReturnSuccess; } virtual IOReturn setGET_DEBUG_INFO(IO80211SkywalkInterface *iface, apple80211_debug_command *dbg) override { return kIOReturnSuccess; }
virtual void* getLogger(void) const override { return nullptr; } virtual void* getLogger(void) const override;
virtual void* getFaultReporterFromDriver(void) override { return nullptr; } virtual void* getFaultReporterFromDriver(void) override;
// Dispatcher de requêtes Apple80211 / airportd // Dispatcher de requêtes Apple80211 / airportd
SInt32 handleApple80211Request(unsigned int req_type, int req_val, void* req_data); SInt32 handleApple80211Request(unsigned int req_type, int req_val, void* req_data);