Pixel BigWave BIGO timeout race UAF → mediacodec에서 2KB 커널 쓰기
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
TL;DR
- SELinux로 제한된 mediacodec 컨텍스트에서
/dev/bigwave(Pixel AV1 hardware accelerator)에 접근할 수 있습니다. 작업이 쌓이면BIGO_IOCX_PROCESS가 **16s wait_for_completion_timeout()**에 걸려 반환되는 동안 워커 스레드가 동일한 inlinejob구조를 동시에 dequeue할 수 있습니다. - FD를 즉시 닫으면
struct bigo_inst(내부에struct bigo_job을 포함)가 해제됩니다. 워커는inst = container_of(job, ...)을 재구성하고 이후bigo_run_job()내부에서job->regs같은 해제된 필드를 사용하여 inline job/inst에 대한 Use-After-Free를 유발합니다. bigo_pull_regs(core, job->regs)는memcpy_fromio(regs, core->base, core->regs_size)를 수행합니다. 해제된 slab를 재할당하고job->regs를 덮어쓰면, 공격자는 타깃 주소에 대해 약 2144바이트 임의의 커널 쓰기를 얻을 수 있으며, 타임아웃 전에 레지스터 값을 미리 설정해 바이트의 일부를 제어할 수 있습니다.- 이 취약점은 CVE-2025-36934로 추적되며; 2026-01-05 Pixel / 2025-12-01 ASB 빌드에서 수정되었습니다.
Attack surface mapping (SELinux → /dev reachability)
- DriverCartographer와 같은 도구를 사용해 특정 SELinux 도메인에서 접근 가능한 디바이스 노드를 열거하세요. mediacodec의 제한된 정책(software decoders는 격리된 컨텍스트에 있어야 함)에도 불구하고
/dev/bigwave는 접근 가능 상태로 남아 있었고, post-media-RCE 코드에 큰 공격 표면을 노출했습니다.
Vulnerability: BIGO_IOCX_PROCESS timeout vs worker
- 흐름: ioctl은 사용자 레지스터 버퍼를
job->regs로 복사하고 inlinejob을 큐에 넣은 뒤wait_for_completion_timeout(..., 16s)를 호출합니다. 타임아웃 시 dequeue/취소를 시도하고 유저스페이스로 반환합니다. - 그 사이에
bigo_worker_thread는 동일한job을 방금 dequeue했을 수 있습니다:
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가 timeout 이후 FD를 닫으면,
inst/job는 worker가 계속 사용하는 동안 해제되어 → UAF가 발생합니다. FD 수명과 worker 스레드의 job 포인터를 묶는 동기화가 없습니다.
익스플로잇 개요
- 대기열 + 타임아웃: worker가 지연되도록 충분한 job을 큐에 넣은 뒤,
BIGO_IOCX_PROCESS를 발행하고 16s 타임아웃 경로에 도달하게 합니다. - 사용 중에 해제: ioctl이 반환되자마자
close(fd)로 worker가 아직 실행 중인 디큐된 job의inst/job를 해제합니다. - 재할당 + 포인터 제어: 반환된 slab 슬롯을 차지하도록 reclaimers(예: Unix domain socket message 할당)를 스프레이해서 inline
job—특히job->regs—를 덮어씁니다. - 임의 쓰기:
bigo_pull_regs()가 실행되면memcpy_fromio()가 MMIO로부터 **core->regs_size (~2144 bytes)**만큼을 공격자가 제공한 주소인job->regs로 써서, KASLR leak 없이 대규모의 write-what-where를 만듭니다. - 데이터 조형: 레지스터가 먼저 사용자 데이터(
bigo_push_regs)로부터 설정되기 때문에, 하드웨어가 실행하지 않도록 레지스터 값을 설정해 복사된 레지스터 이미지가 공격자가 제어하는 바이트에 가깝게 유지되도록 합니다.
최소 PoC 골격 (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를 idle 상태로 미리 구성해야 합니다(예: 실행을 건너뛰도록 제어 비트 설정).
드라이버 리뷰어를 위한 요점
- async workers에 enqueued된 inline per-FD job struct는 timeout/취소 경로에서도 유효한 참조를 유지해야 합니다; FD를 닫는 동작은 worker의 소비와 동기화되어야 합니다.
- jobs에서 온 버퍼 포인터를 사용하는 모든 MMIO 복사 헬퍼(
memcpy_fromio/memcpy_toio)는 enqueuing 전에 검증하거나 복제해야 UAF→write primitives를 방지할 수 있습니다.
참고자료
- Pixel 0-click (Part 2): Escaping the mediacodec sandbox via the BigWave driver
- Project Zero issue 426567975 – BigWave BIGO timeout UAF
- CVE-2025-36934 entry (BigWave driver)
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


