
Öffentliche Offenlegung für CVE-2026-43655 AppleM2ScalerCSCDriver use-after-free
Öffentliche technische Offenlegung für CVE-2026-43655, ein Use-after-Free im AppleM2ScalerCSCDriver / IOSurfaceAccelerator, der aus der standardmäßigen iOS-App-Sandbox ohne besondere Berechtigungen erreichbar ist.
Apple hat dieses Problem in iOS 26.5 / iPadOS 26.5 / macOS Tahoe 26.5 behoben. Dieses Repository enthält den Objective-C-Proof-of-Concept-Quellcode, minimale Berechtigungen, ein gebautes IPA und die technische Beschreibung, die zum Verständnis und zur Reproduktion des Problems auf einem betroffenen Gerät erforderlich sind.
Der Fehler ist ein Lebensdauerfehler beim Abbau im Scaler-Scheduler. Ein Benutzerprozess kann asynchrone Scaler-Operationen einreichen, die IOSurfaceAcceleratorClient-Verbindung schließen, die diese Operationen besitzt, und veraltete Einträge in einer treiberglobalen Scheduler-Struktur hinterlassen. Ein späterer Scheduler-Durchlauf kann dann Einträge verarbeiten, die immer noch auf bereits freigegebenen und wiederverwendeten Operationsspeicher verweisen.
Der PoC demonstriert den Lebensdauerfehler mit zwei verschiedenen Markierungswerten:
0xDEAD00010xBEEF0002Die Opferverbindung reicht asynchrone Operationen ein und wird dann geschlossen. Ersatzverbindungen werden danach geöffnet und setzen ihre eigene Markierung auf 0xBEEF0002. Wenn der nächste Scaler-Scheduling-Zyklus läuft, beobachtet der Fehler die Ersatzmarkierung (x9 = 0x00000000BEEF0002), nicht die Opfermarkierung. Das beweist, dass der Scheduler aus einem Operationsslot gelesen hat, der freigegeben und dann einer anderen Verbindung zugewiesen wurde.
com.apple.driver.AppleM2ScalerCSCDriverIOSurfaceAcceleratorClientget-task-allowAppleM2ScalerCSCDriver hält den Scheduler-Zustand gemeinsam für alle Scaler-Clients. Die relevante Lebensdauerinkonsistenz ist:
IOServiceClose geschlossen.Der Abbau-Pfad entfernt die ausstehenden Scheduler-Einträge des schließenden Clients nicht aus dem gemeinsamen Scheduler-Heap. Der Scheduler liest und schreibt später Felder durch diese veralteten Zeiger.
Wichtige während der Analyse beobachtete Felder:
| Offset | Scheduler-Verhalten |
|---|---|
operation + 0xc94 | wird als Credit-/Markierungswert vom Credit-Auflösungspfad gelesen |
operation + 0xc1c | wird vom Scheduler-Credit-Accounting-Pfad geschrieben |
operation + 0x1fe4 | wird vom Scheduler-Zustands-/Flag-Aktualisierungspfad geschrieben |
Das Verhalten des Operations-Allokators macht den Fehler beobachtbar: Freigegebene Operationsslots können von späteren Operationen anderer Verbindungen wiederverwendet werden. Durch Schließen einer Opferverbindung und sofortiges Sprayen neuer Verbindungen kann der PoC veraltete Scheduler-Einträge dazu bringen, auf Speicher zu zeigen, der jetzt den Spray-Verbindungen gehört.
x9 = 0xBEEF0002 den Use-After-Free beweistDer PoC verwendet eine Unterscheidung zwischen Opfer und Spray:
0xDEAD0001.0xBEEF0002.Wenn der Scheduler immer noch live vom Opfer besessene Objekte lesen würde, wäre der beobachtete Wert 0xDEAD0001. Stattdessen beobachtet der reproduzierte Fehler 0xBEEF0002, den von den ersetzenden Spray-Verbindungen geschriebenen Wert. Das ist der Hauptbeweis, dass der Scheduler einen veralteten Zeiger auf freigegebenen und wiederverwendeten Kernel-Speicher dereferenziert.
Dies zeigt auch eine verbindungsübergreifende Auswirkung: Der Scheduler-Eintrag wurde von einer Verbindung erstellt, aber der Speicher, den er später berührte, wurde für eine andere Verbindung recycelt. In reproduzierten Läufen konnte die endgültige Scheduler-Aktivität durch normale SpringBoard-/Compositor-/UI-Aktivität und nicht durch den ursprünglichen PoC-Prozess ausgelöst werden.
Die öffentliche Apple-Beratung beschreibt die Auswirkungen als: “Eine App kann möglicherweise einen unerwarteten Systemabbruch verursachen oder Kernel-Speicher lesen.”
Wichtiges Reproduktionsdetail: Nach dem Tippen auf TEARDOWN UAF stürzt das Gerät nicht unbedingt sofort ab. Der PoC erstellt zuerst einen veralteten Scheduler-Zustand. Der Fehler tritt beim nächsten Scaler-Scheduling-Zyklus auf, der in der Praxis auftritt, wenn SpringBoard-/Compositor-Aktivität den Scaler antreibt. Bei meiner physischen Geräte-Reproduktion habe ich diesen Scheduler-Zyklus durch Tippen/Interagieren mit der Dynamic Island ausgelöst, nachdem der PoC den veralteten Scheduler-Zustand erstellt hatte.
Schritte:
ScalerTeardownUAF.ipa.AppleM2ScalerCSCDriver.IOSurface-Objekte.0xDEAD0001 auf der Opfer-Verbindung.IOServiceClose, wodurch die vom Opfer besessenen Operationsobjekte freigegeben werden, während veraltete Scheduler-Einträge bestehen bleiben.0xBEEF0002.x9 = 0x00000000BEEF0002 enthält.Erwartete Beweisbedingung:
x9 = 0x00000000BEEF0002 bedeutet, dass der Scheduler die Spray-Markierung aus Speicher gelesen hat, der ursprünglich zur freigegebenen Opfer-Operation gehörte.0xBEEF0002 ist nicht die Opfermarkierung; es ist die Ersatzverbindungsmarkierung.Der enthaltene Quellcode führt die folgende Sequenz aus:
Öffne Opfer-Verbindung
Erstelle IOSurface-Quell-/Ziel-Paar
Reiche synchrone Basislinien-Scaler-Anfrage ein
Setze Opfer-Markierung = 0xDEAD0001 über Selektor 10
Reiche 50 asynchrone Scaler-Operationen ein
Schließe Opfer-Verbindung
Öffne 50 Spray-Verbindungen
Setze Spray-Markierung = 0xBEEF0002 über Selektor 10
Reiche wiederholte asynchrone Scaler-Operationen auf Spray-Verbindungen ein
Warte auf SpringBoard-/Compositor-Scheduler-Trigger
Die relevante Quelldatei ist ScalerTeardownUAF.m.
xcrun -sdk iphoneos clang -framework Foundation -framework UIKit -framework IOKit \
-framework IOSurface -isysroot $(xcrun --sdk iphoneos --show-sdk-path) \
-arch arm64 -arch arm64e -miphoneos-version-min=16.0 -fobjc-arc \
-o iPhoneProbe.app/iPhoneProbe ScalerTeardownUAF.m
ldid -S entitlements.plist iPhoneProbe.app/iPhoneProbe
mkdir -p /tmp/pkg/Payload
cp -r iPhoneProbe.app /tmp/pkg/Payload/
cd /tmp/pkg && zip -qr ScalerTeardownUAF.ipa Payload
AppleM2ScalerCSCDriver-Verhaltens gefunden.0xDEAD0001, Spray 0xBEEF0002.| Datei | Beschreibung |
|---|
ScalerTeardownUAF.m | Objective-C-PoC-Quelle, die die Sequenz von Opfer-Schließen + Spray-Wiederverwendung implementiert. |
ScalerTeardownUAF.ipa | Gebautes IPA-Reproduktionsartefakt. |
entitlements.plist | Minimale Berechtigungsdatei mit get-task-allow. |