Pixel BigWave BIGO timeout race UAF → 2KB kernel write from mediacodec

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

TL;DR

  • SELinux ile kısıtlanmış mediacodec bağlamından /dev/bigwave (Pixel AV1 donanım hızlandırıcısı) erişilebilir. İş kuyruğunun birikmesi, BIGO_IOCX_PROCESS’in 16s wait_for_completion_timeout() süresine takılmasına ve dönerken worker thread’in aynı inline job yapısını eşzamanlı olarak kuyruktan çıkarmasına neden olur.
  • FD’yi kapatmak hemen struct bigo_inst’i (içine gömülü struct bigo_job) serbest bırakır. Worker, inst = container_of(job, ...) ile yeniden yapılandırır ve daha sonra bigo_run_job() içinde serbest bırakılmış alanlar, ör. job->regs, kullanılır; bu da inline job/inst üzerinde bir Use-After-Free oluşturur.
  • bigo_pull_regs(core, job->regs) memcpy_fromio(regs, core->base, core->regs_size) gerçekleştirir. Serbest bırakılan slab geri kazanılıp job->regs üzerine yazılarak, saldırgan seçilen bir adrese yaklaşık 2144 baytlık keyfi kernel yazma elde eder; timeout öncesinde register değerlerini önceden programlayarak baytların bir kısmı üzerinde kısmi kontrol sağlanabilir.
  • Takip edilen kayıtlarda CVE-2025-36934; 2026-01-05 Pixel/2025-12-01 ASB build’lerinde düzeltildi.

Attack surface mapping (SELinux → /dev reachability)

  • Belirli bir SELinux domain’inden erişilebilir device node’ları listelemek için DriverCartographer gibi araçlar kullanın. mediacodec’in sınırlı politikası (yazılım decoder’larının izole bir bağlamda kalması gerektiği) olmasına rağmen, /dev/bigwave erişilebilir kaldı ve post-media-RCE koduna geniş bir saldırı yüzeyi açtı.

Vulnerability: BIGO_IOCX_PROCESS timeout vs worker

  • Akış: ioctl, kullanıcı register buffer’ını job->regs’e kopyalar, inline job’u kuyruğa ekler, ardından wait_for_completion_timeout(..., 16s) çağrılır. Timeout olduğunda dequeue/iptal etmeye çalışır ve userspace’e döner.
  • Bu sırada bigo_worker_thread aynı job’u kuyruktan çıkarmış olabilir:
inst = container_of(job, struct bigo_inst, job);
bigo_push_regs(core, job->regs);
...
bigo_pull_regs(core, job->regs);   // memcpy_fromio(regs, core->base, core->regs_size)
*(u32 *)(job->regs + BIGO_REG_STAT) = status;
  • Eğer userspace timeout’tan sonra FD’yi kapatırsa, inst/job serbest bırakılırken worker onları kullanmaya devam eder → UAF. FD ömrünü worker thread’in job pointer’ına bağlayan bir senkronizasyon yok.

İstismar özeti

  1. Backlog + timeout: Worker’ın gecikmesi için yeterli sayıda job kuyruğa koyun, sonra BIGO_IOCX_PROCESS gönderin ve 16s timeout yoluna girmesine izin verin.
  2. Free while in use: ioctl döner dönmez, worker hâlâ kuyruğundan çıkarılan job’ı çalıştırırken close(fd) ile inst/job’ı serbest bırakın.
  3. Reclaim + pointer control: Serbest kalan slab slotunu işgal etmek ve inline job’u, özellikle job->regs’i ezmek için reclaimers (ör. Unix domain socket message tahsisleri) ile spray yapın.
  4. Arbitrary write: bigo_pull_regs() çalıştığında, memcpy_fromio() MMIO’dan core->regs_size (~2144 bytes) kadar veriyi job->regs içindeki saldırgan kontrollü adrese yazar; bu, KASLR leak’i olmadan büyük bir write-what-where üretir.
  5. Data shaping: Kayıtlar önce kullanıcı verisinden (bigo_push_regs) programlandığı için, donanımın çalıştırmaması için onları ayarlayın; böylece geri kopyalanan kayıt görüntüsü saldırgan kontrollü baytlara yakın kalır.

Minimal PoC skeleton (blocking backlog + reclaim)

int fd = open("/dev/bigwave", O_RDWR);
for (int i = 0; i < 64; i++) submit_job(fd, regs_buf);   // fill worker queue
submit_job(fd, regs_buf);                                // victim job
auto t0 = now();
while (now() - t0 < 17000ms) sched_yield();              // hit 16s timeout
close(fd);                                               // free inst/job
spray_uds_msgs(payload_pointing_to_target, spray_count); // reclaim slab
sleep(1);                                                // let worker memcpy_fromio
  • regs_buf BigWave’i idle duruma getirecek şekilde ön yapılandırılmalıdır (ör. yürütmeyi atlamak için kontrol bitleri ayarlanarak) böylece kopyalanıp geri getirilen register görüntüsü tutarlı kalır.

Sürücü inceleyenler için çıkarımlar

  • Inline per-FD job struct’ları (async worker’lara sıraya alınan) zaman aşımı/iptal yollarından sağ çıkacak referansları tutmalıdır; bir FD’nin kapatılması worker tüketimiyle senkronize edilmelidir.
  • Job’lardan gelen buffer pointer’larını kullanan herhangi bir MMIO kopya yardımcısı (memcpy_fromio/memcpy_toio) UAF→write primitive’lerini önlemek için sıraya alınmadan önce doğrulanmalı veya kopyalanmalıdır.

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin