Files
Erwan 0809b01856 fix(wifi): prevent CPU triple fault and instant reboot via CCLogStream layout conforming FakeLogStream
### Breakthroughs & Rétro-ingénierie
- Analyse forensique du redémarrage instantané ("coupure de courant" sans log) survenu au commit 5357ca6 :
  1. Le désassemblage de `CCLogStream::shouldLog` (0xffffff80032ff9e6) dans `BootKernelExtensions.kc` a révélé un déréférencement en cascade non protégé : `movq 0x90(%rdi), %rax` puis `movq 0x58(%rax), %rax`.
  2. `fLogger` retournant un `OSString*` de seulement 32 octets (0x20), l'accès à +0x90 lisait une adresse arbitraire du tas kernel dont le déréférencement en Ring 0 déclenchait un #PF/#GP transformé en Triple Fault CPU immédiat (reset matériel sans panic handler).
  3. Parallèlement, `IO80211RNGAgent::withOptions` et `IO80211ControllerMonitor::withControllerAndProvider` requièrent impérativement un pointeur non-nul et invoquent `logger->retain()` (*0x20(%rax)).
  4. La résolution consiste en une classe `FakeLogStream : public OSObject` respectant au millimètre l'ABI Apple : un pointeur `p1` placé à l'offset strict +0x90 (validé par `static_assert`) pointant vers une zone mémoire `fP1Mem` dont l'offset +0x58 pointe vers `fP2Mem` initialisé à zéro. `shouldLog` et `log*` retournent ainsi false sans aucun déréférencement illégal et sans risquer d'écrire sur un pipe non configuré.

### Modifications apportées
- `QualcommWifi/QualcommWifi.cpp` :
  - Définition et enregistrement IOKit de `FakeFaultReporter` et `FakeLogStream` avec méthodes usine `create()`.
  - Initialisation de `fFaultReporter = FakeFaultReporter::create()` et `fLogger = FakeLogStream::create()` dans `init()`.
  - Implémentation locale de `QualcommWifi::getActionFramePoolCapacity()` (slot 440) renvoyant 0x100 (256 frames).
  - Suppression de l'écriture directe `kIOPCIConfigCommand` sur le bus PCIe AMD pendant `start()` afin d'éviter tout conflit de bridge ou transaction d'arbitrage invalidée.
  - Nettoyage du buffer statique non-thread-safe dans `logNvramStage`.
- `QualcommWifi/QualcommWifi.hpp` :
  - Déclaration de `virtual UInt32 getActionFramePoolCapacity(void) override`.
- `build_wifi.sh` :
  - Ajout du flag `-Wno-invalid-offsetof` pour compilation propre de l'assertion ABI.
- `docs/ISSUES_AND_POSTMORTEMS.md` :
  - Documentation détaillée du post-mortem INC-10 expliquant le mécanisme de triple fault et la solution apportée.

### Validation
- Compilation réussie avec 0 erreur.
- Vérification de la vtable `__ZTV12QualcommWifi` : taille exacte de 3728 octets (0xe90, 466 slots) conforme à OpenCore et Apple `IO80211Controller`.
- Validation de conformité des symboles et dépendances à 100% via `kmutil libraries`.
- Déploiement du kext compilé dans `/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext`.
- Activation confirmée dans `/Volumes/EFI/EFI/OC/config.plist` (`Enabled = True`).
2026-10-17 23:14:09 +02:00

60 lines
2.4 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="${SCRIPT_DIR}/build/Release"
KEXT_BUNDLE="${BUILD_DIR}/QualcommWifi.kext"
KEXT_MACOS="${KEXT_BUNDLE}/Contents/MacOS"
SDK_PATH="$(xcrun --show-sdk-path)"
echo "=== Compilation de QualcommWifi.kext (macOS Tahoe 26.x / Darwin 25) ==="
mkdir -p "${KEXT_MACOS}"
# 1. Assemblage du firmware embarqué (AMSS, Board-2, M3)
echo "[1/5] Assemblage du firmware radio WCN7850..."
clang -target x86_64-apple-macos26.5 \
-c "${SCRIPT_DIR}/QualcommWifi/Firmware_WCN7850_Wifi.s" \
-o "${BUILD_DIR}/Firmware_WCN7850_Wifi.o"
# 2. Compilation C++ du pilote QualcommWifi
echo "[2/5] Compilation C++ de QualcommWifi.cpp..."
clang++ -target x86_64-apple-macos26.5 \
-nostdinc -isystem "${SDK_PATH}/System/Library/Frameworks/Kernel.framework/Headers" \
-I"${SCRIPT_DIR}/QualcommWireless/include" \
-I"${SCRIPT_DIR}/QualcommWifi" \
-std=c++17 -fno-builtin -fno-common -mkernel -fno-rtti -fno-exceptions \
-fno-stack-protector -fno-strict-aliasing -Wno-invalid-offsetof -Os \
-DKERNEL -D__IO80211_TARGET=260000 -DAPPLE_KEXT_OVERRIDE=override \
-c "${SCRIPT_DIR}/QualcommWifi/QualcommWifi.cpp" \
-o "${BUILD_DIR}/QualcommWifi.o"
# 3. Compilation C du module kmod (kmod_info, start/stop pour OpenCore / PrelinkedKernel)
echo "[3/5] Compilation C de QualcommWifi_info.c..."
clang -target x86_64-apple-macos26.5 \
-nostdinc -isystem "${SDK_PATH}/System/Library/Frameworks/Kernel.framework/Headers" \
-std=c99 -fno-builtin -mkernel \
-c "${SCRIPT_DIR}/QualcommWifi/QualcommWifi_info.c" \
-o "${BUILD_DIR}/QualcommWifi_info.o"
# 4. Édition de liens (Mach-O Kext avec libkmod)
echo "[4/5] Édition de liens du binaire Kext..."
clang++ -target x86_64-apple-macos26.5 \
-nostdlib -mkernel -Xlinker -kext \
-Xlinker -dead_strip \
"${BUILD_DIR}/QualcommWifi.o" \
"${BUILD_DIR}/Firmware_WCN7850_Wifi.o" \
"${BUILD_DIR}/QualcommWifi_info.o" \
"${SDK_PATH}/usr/lib/libkmod.a" \
-o "${KEXT_MACOS}/QualcommWifi"
# 5. Copie de Info.plist et signature ad-hoc
echo "[5/5] Copie de Info.plist et signature..."
cp "${SCRIPT_DIR}/QualcommWifi/Info.plist" "${KEXT_BUNDLE}/Contents/Info.plist"
codesign -s - -f "${KEXT_BUNDLE}"
echo "=== Validation des bibliothèques et symboles avec kmutil ==="
kmutil libraries -p "${KEXT_BUNDLE}" > /dev/null
echo "✓ Validation kmutil réussie à 100% contre BootKernelExtensions.kc !"
echo "Kext produit : ${KEXT_BUNDLE}"