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

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

TL;DR

  • Από το SELinux-περιορισμένο πλαίσιο mediacodec, το /dev/bigwave (Pixel AV1 hardware accelerator) είναι προσβάσιμο. Μια συσσωρευμένη ουρά jobs κάνει το BIGO_IOCX_PROCESS να χτυπήσει το 16s wait_for_completion_timeout() και να επιστρέψει ενώ το worker thread ταυτόχρονα απο-ουράζει την ίδια inline δομή job.
  • Το κλείσιμο του FD απελευθερώνει άμεσα το struct bigo_inst (που ενσωματώνει το struct bigo_job). Ο worker επανασυνθέτει το inst = container_of(job, ...) και αργότερα χρησιμοποιεί απελευθερωμένα πεδία όπως job->regs μέσα στο bigo_run_job(), προκαλώντας Use-After-Free on the inline job/inst.
  • Η bigo_pull_regs(core, job->regs) εκτελεί memcpy_fromio(regs, core->base, core->regs_size). Με την επανακτήση του απελευθερωμένου slab και την υπερχείλιση του job->regs, ένας επιτιθέμενος αποκτά ~2144-byte arbitrary kernel write σε επιλεγμένη διεύθυνση, με μερικό έλεγχο των bytes προ-προγραμματίζοντας τιμές καταχωρητών πριν το timeout.
  • Καταχωρήθηκε ως CVE-2025-36934· επιδιορθώθηκε στα builds 2026-01-05 Pixel/2025-12-01 ASB.

Attack surface mapping (SELinux → /dev reachability)

  • Χρησιμοποιήστε εργαλεία όπως DriverCartographer για να καταγράψετε τις device nodes προσβάσιμες από ένα δεδομένο SELinux domain. Παρά την περιορισμένη πολιτική του mediacodec (software decoders πρέπει να παραμένουν σε απομονωμένο context), το /dev/bigwave παρέμεινε προσβάσιμο, εκθέτοντας μεγάλη επιφάνεια επίθεσης σε κώδικα post-media-RCE.

Vulnerability: BIGO_IOCX_PROCESS timeout vs worker

  • Ροή: το ioctl αντιγράφει το user register buffer στο job->regs, τοποθετεί στην ουρά το inline job, και στη συνέχεια καλείται το wait_for_completion_timeout(..., 16s). Σε timeout προσπαθεί να απο-ουράρει/ακυρώσει και επιστρέφει στο userspace.
  • Εν τω μεταξύ το bigo_worker_thread μπορεί να έχει μόλις απο-ουράρει το ίδιο job:
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;
  • Εάν το userspace κλείσει το FD μετά το timeout, inst/job απελευθερώνονται ενώ ο worker συνεχίζει να τα χρησιμοποιεί → UAF. Δεν υπάρχει συγχρονισμός που να συνδέει το lifetime του FD με τον δείκτη job του worker thread.

Exploitation outline

  1. Backlog + timeout: Queue αρκετά jobs ώστε ο worker να καθυστερήσει, στη συνέχεια εκτελέστε BIGO_IOCX_PROCESS και αφήστε να φτάσει στο 16s timeout path.
  2. Free while in use: Μόλις το ioctl επιστρέψει, κάντε close(fd) για να απελευθερώσετε inst/job ενώ ο worker εξακολουθεί να τρέχει το dequeued job.
  3. Reclaim + pointer control: Spray reclaimers (π.χ. Unix domain socket message allocations) για να καταλάβετε το freed slab slot και να αντικαταστήσετε το inline job, ειδικά job->regs.
  4. Arbitrary write: Όταν τρέχει bigo_pull_regs(), memcpy_fromio() γράφει core->regs_size (~2144 bytes) από MMIO στη διεύθυνση που παρέχει ο attacker μέσα σε job->regs, παράγοντας ένα μεγάλο write-what-where χωρίς KASLR leak.
  5. Data shaping: Επειδή τα registers πρώτα προγραμματίζονται από user data (bigo_push_regs), ρυθμίστε τα ώστε το hardware να μην εκτελέσει, κρατώντας την επιστρεφόμενη εικόνα registers κοντά σε bytes που ελέγχει ο attacker.

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 ώστε να είναι σε κατάσταση αδράνειας (π.χ., ορίζοντας bits ελέγχου για να παρακαμφθεί η εκτέλεση) έτσι ώστε η εικόνα καταχωρητών που αντιγράφηκε πίσω να παραμένει ντετερμινιστική.

Σημεία προς αναθεωρητές του driver

  • Οι inline per-FD job structs που τοποθετούνται σε async workers πρέπει να κρατούν αναφορές που επιβιώνουν σε μονοπάτια timeout/cancel· το κλείσιμο ενός FD πρέπει να συγχρονίζεται με την κατανάλωση από τον worker.
  • Οποιοιδήποτε MMIO copy helpers (memcpy_fromio/memcpy_toio) που χρησιμοποιούν buffer pointers από jobs πρέπει να επικυρώνονται ή να διπλασιάζονται πριν την τοποθέτηση στην ουρά, για να αποφευχθούν UAF→write primitives.

Αναφορές

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks