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

TL;DR

  • 从受 SELinux 限制的 mediacodec 上下文,可以访问 /dev/bigwave(Pixel AV1 硬件加速器)。作业积压会导致 BIGO_IOCX_PROCESS 命中其 16s wait_for_completion_timeout() 并返回,同时工作线程并发地从队列中取出相同的内联 job 结构。
  • 关闭 FD 立即释放 struct bigo_inst(其中嵌入了 struct bigo_job)。工作线程通过重构 inst = container_of(job, ...) 恢复并在 bigo_run_job() 中使用已释放的字段(例如 job->regs),从而导致内联 job/inst 的 Use-After-Free
  • bigo_pull_regs(core, job->regs) 会执行 memcpy_fromio(regs, core->base, core->regs_size)。通过回收被释放的 slab 并覆盖 job->regs,攻击者可以对选定地址获得 ~2144-byte arbitrary kernel write,并通过在超时前预先设置寄存器值部分控制写入的字节。
  • 被追踪为 CVE-2025-36934;在 2026-01-05 Pixel/2025-12-01 ASB 构建中修复。

Attack surface mapping (SELinux → /dev reachability)

  • 使用诸如 DriverCartographer 的工具枚举从给定 SELinux 域可访问的设备节点。尽管 mediacodec 的策略受限(软件解码器应保持在隔离上下文),/dev/bigwave 仍然可达,从而把大量攻击面暴露给 post-media-RCE 代码。

Vulnerability: BIGO_IOCX_PROCESS timeout vs worker

  • 流程:ioctl 将用户寄存器缓冲区复制到 job->regs,将内联 job 入队,然后调用 wait_for_completion_timeout(..., 16s)。超时后它尝试出队/取消并返回到 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,inst/job 会被释放,而 worker 仍在使用它们 → UAF。没有任何同步将 FD 的生命周期与 worker 线程的 job 指针关联。

利用概述

  1. Backlog + timeout: 排队足够多的 jobs 以使 worker 被延迟,然后发起 BIGO_IOCX_PROCESS 并让它走到 16s 的超时路径。
  2. Free while in use: 一旦 ioctl 返回,立刻 close(fd) 释放 inst/job,而 worker 仍在运行被出队的 job。
  3. Reclaim + pointer control: 喷射 reclaimers(例如 Unix domain socket message allocations)以占据被释放的 slab 插槽并覆盖内联的 job,尤其是 job->regs
  4. Arbitrary write:bigo_pull_regs() 运行时,memcpy_fromio()core->regs_size (~2144 bytes) 从 MMIO 写入到攻击者在 job->regs 中提供的地址,从而产生一个大规模的 write-what-where,而无需 KASLR leak。
  5. Data shaping: 由于寄存器最初是从用户数据(bigo_push_regs)编程的,设置它们以使硬件不执行,从而保持被复制回的寄存器镜像接近攻击者控制的字节。

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 进入空闲(例如,设置控制位以跳过执行),以便复制回来的寄存器镜像保持确定性。

驱动审查要点

  • Inline per-FD job structs enqueued to async workers must hold references that survive timeout/cancel paths; closing an FD must synchronize with worker consumption.
  • 任何使用来自 jobs 的 buffer 指针的 MMIO copy helpers (memcpy_fromio/memcpy_toio) 应在入队之前进行验证或复制,以避免 UAF→write 原语。

References

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