We recently published an exploit chain for the Google Pixel 9 that demonstrated it was possible to go from a zero-click context to root on Android in just two exploits. The Dolby 0-click vulnerability existed across all of Android, until it was patched in January 2026. While we had an exploit chain for the Pixel 9, we wanted to see if it was possible to write a similar exploit chain for Pixel 10.
Updating the Dolby Exploit
Altering our exploit for CVE-2025-54957 was fairly straightforward. The majority of needed changes involved updating offsets calculated for the specific version of the library we targeted on the Pixel 9 to similar offsets in the library for Pixel 10. The only challenge (outside of wishing we’d better documented which syncframes contained offsets) was that the Pixel 10 uses RET PAC in the place of -fstack-protector , which meant that __stack_chk_fail wasn’t available to be overwritten by code. After a bit of trial and error, we used dap_cpdp_init , initialization code that can be overwritten without causing functional problems, as it is called once when the decoder is initialized and never again. The updated Dolby UDC exploit is available here. This exploit will only work on unpatched devices (SPL December 2025 or earlier).
Removal of BigWave, Addition of VPU
Porting the local privilege escalation link of the chain to Pixel 10 was not feasible as the BigWave driver does not ship on this device. However, a new driver is visible in the mediacodec SELinux context at /dev/vpu. This driver is used for interacting with the Chips&Media Wave677DV silicon on the Tensor G5 chip meant for accelerating video decoding. Based on the comments within the open-source C files, this driver is developed and maintained by the same set of developers who built the BigWave driver. Working in collaboration with Jann Horn, we spent 2 hours auditing this VPU driver and discovered an exceptional vulnerability.
Unlike the upstream Linux driver for WAVE521C (which is an older Chips&Media chip), the Pixel driver for WAVE677DV does not integrate with V4L2 (the “Video for Linux API”); instead, it directly exposes the chip’s hardware interface to userspace, including letting userspace map the chip’s MMIO register interface. The driver mainly establishes device memory mappings, does power management, and allows userspace to wait for interrupts from the chip.
The Holy Grail of Kernel Vulnerabilities
This bug in particular caught our attention as exceptionally simple to exploit:
static int vpu_mmap ( struct file * fp , struct vm_area_struct * vm ) { unsigned long pfn ; struct vpu_core * core = container_of ( fp -> f_inode -> i_cdev , struct vpu_core , cdev ); vm_flags_set ( vm , VM_IO | VM_DONTEXPAND | VM_DONTDUMP ); /* This is a CSRs mapping, use pgprot_device */ vm -> vm_page_prot = pgprot_device ( vm -> vm_page_prot ); pfn = core -> paddr >> PAGE_SHIFT ; return remap_pfn_range ( vm , vm -> vm_start , pfn , vm -> vm_end - vm -> vm_start , vm -> vm_page_prot ) ? - EAGAIN : 0 ; }
This mmap handler is intended to be used in order to map the MMIO register region of the VPU hardware into the userland virtual address space - a region contained within a certain physical memory address range. In doing so, it makes a call to remap_pfn_range based purely on the size of the VMA and not at all bounded to the size of this register region. This means that, by specifying a size larger than the register region in an mmap syscall, the caller can map as much physical memory as they want into userland, starting at the physical address of the VPU register region. The entirety of the kernel image (including .text, and .data region) is located at a higher physical address than the VPU register region, and can therefore be accessed and modified by userspace with this bug.
... continue reading