
Divulgação pública para CVE-2026-43655 AppleM2ScalerCSCDriver use-after-free
Divulgação técnica pública para CVE-2026-43655, um use-after-free no AppleM2ScalerCSCDriver / IOSurfaceAccelerator acessível a partir da sandbox padrão de aplicativos iOS sem autorizações especiais.
A Apple corrigiu esse problema no iOS 26.5 / iPadOS 26.5 / macOS Tahoe 26.5. Este repositório contém o código-fonte da prova de conceito em Objective-C, autorizações mínimas, um IPA compilado e a descrição técnica necessária para entender e reproduzir o problema em um dispositivo afetado.
O bug é um erro de destruição/tempo de vida no agendador do scaler. Um processo de usuário pode enviar operações assíncronas do scaler, fechar a conexão IOSurfaceAcceleratorClient que possui essas operações e deixar entradas obsoletas em uma estrutura de agendador global do driver. Uma passagem posterior do agendador pode então processar entradas que ainda apontam para armazenamento de operação que já foi liberado e reutilizado.
O PoC demonstra o bug de tempo de vida com dois valores de marcador distintos:
0xDEAD00010xBEEF0002A conexão vítima envia operações assíncronas e é então fechada. Conexões de substituição são abertas posteriormente e definem seu próprio marcador como 0xBEEF0002. Quando o próximo ciclo de agendamento do scaler é executado, a falha observa o marcador de substituição (x9 = 0x00000000BEEF0002), não o marcador da vítima. Isso prova que o agendador leu de um slot de operação que havia sido liberado e depois realocado para uma conexão diferente.
com.apple.driver.AppleM2ScalerCSCDriverIOSurfaceAcceleratorClientget-task-allowAppleM2ScalerCSCDriver mantém o estado do agendador compartilhado entre clientes do scaler. A incompatibilidade de tempo de vida relevante é:
IOServiceClose.O caminho de destruição não remove as entradas pendentes do agendador do cliente que está fechando do heap do agendador compartilhado. O agendador posteriormente lê e escreve campos através desses ponteiros obsoletos.
Campos importantes observados durante a análise:
| Offset | Comportamento do agendador |
|---|---|
operation + 0xc94 | lido como o valor de crédito/marcador usado pelo caminho de resolução de crédito |
operation + 0xc1c | escrito pelo caminho de contabilidade de crédito do agendador |
operation + 0x1fe4 | escrito pelo caminho de atualização de estado/sinalização do agendador |
O comportamento do alocador de operações torna o bug observável: slots de operação liberados podem ser reutilizados por operações posteriores de diferentes conexões. Ao fechar uma conexão vítima e imediatamente pulverizar novas conexões, o PoC pode fazer com que entradas obsoletas do agendador apontem para memória agora de propriedade das conexões de spray.
x9 = 0xBEEF0002 prova UAFO PoC usa uma distinção vítima/spray:
0xDEAD0001.0xBEEF0002.Se o agendador ainda estivesse lendo objetos vivos de propriedade da vítima, o valor observado seria 0xDEAD0001. Em vez disso, a falha reproduzida observa 0xBEEF0002, o valor escrito pelas conexões de spray de substituição. Essa é a prova chave de que o agendador está desreferenciando um ponteiro obsoleto para memória do kernel liberada e reutilizada.
Isso também mostra o impacto entre conexões: a entrada do agendador foi criada por uma conexão, mas a memória que ela posteriormente tocou foi reciclada para outra conexão. Em execuções reproduzidas, a atividade final do agendador pode ser impulsionada pela atividade normal do SpringBoard/compositor/UI, em vez do processo PoC original.
O aviso público da Apple descreve o impacto como: “Um aplicativo pode ser capaz de causar término inesperado do sistema ou ler memória do kernel.”
Detalhe importante da reprodução: após tocar em TEARDOWN UAF, o dispositivo não necessariamente entra em pânico imediatamente. O PoC primeiro prepara o estado obsoleto do agendador. O bug é acionado no próximo ciclo de agendamento do scaler, que na prática ocorre quando a atividade do SpringBoard/compositor aciona o scaler. Na minha reprodução em dispositivo físico, acionei esse ciclo do agendador tocando/interagindo com a Dynamic Island após o PoC terminar de preparar o estado obsoleto do agendador.
Passos:
ScalerTeardownUAF.ipa.AppleM2ScalerCSCDriver.IOSurface de origem/destino.0xDEAD0001 na conexão vítima.IOServiceClose, liberando objetos de operação de propriedade da vítima enquanto entradas obsoletas do agendador permanecem.0xBEEF0002.x9 = 0x00000000BEEF0002.Condição de prova esperada:
x9 = 0x00000000BEEF0002 significa que o agendador leu o marcador de spray da memória que originalmente pertencia à operação vítima liberada.0xBEEF0002 não é o marcador da vítima; é o marcador da conexão de substituição.O código-fonte incluído executa a seguinte sequência:
open victim connection
create IOSurface source/destination pair
submit sync baseline scaler request
set victim marker = 0xDEAD0001 through selector 10
submit 50 async scaler operations
close victim connection
open 50 spray connections
set spray marker = 0xBEEF0002 through selector 10
submit repeated async scaler operations on spray connections
wait for SpringBoard/compositor scheduler trigger
O arquivo de código-fonte relevante é 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
| Arquivo | Descrição |
|---|---|
ScalerTeardownUAF.m | Código-fonte do PoC em Objective-C implementando a sequência de fechamento da vítima + reutilização por spray. |
ScalerTeardownUAF.ipa | Artefato de reprodução IPA compilado. |
entitlements.plist | Arquivo de autorização mínimo contendo get-task-allow. |
AppleM2ScalerCSCDriver.0xDEAD0001, spray 0xBEEF0002.