



Executive Summary
\nParts 1 and 2 were the lockpicks. Part 3 is the building inspection. Natalie Silvanovich writes the series close as an ecosystem argument, not a third exploit. The 0-click chain was two software defects: a Dolby decoder on the transcription path, and an AV1 driver the decoder sandbox is allowed to open. Finding them took days once the surface was mapped. Exploiting them took single-digit person-weeks. Pixel shipped the decoder fix 82 days after the bug was public. Android first rated the remote decoder bug Moderate because mediacodec is a constrained context; Samsung rated it Critical and patched first. Android has since moved that bucket to Critical. kASLR on Pixel has been a known miss since 2016. The AOSP mediacodec seccomp policy existed and was enforced on other Android 16 devices, not on this Pixel 9. Apple compiled the same UDC with -fbounds-safety; P0 has not exploited it there.
\nThis draft keeps every original section in order, including both Dolby advisory sentences word for word, then adds the kitchen picture, a dated calendar, the severity split, and a CISO-length reading of diffusion of responsibility. There are no original figures or code blocks in Part 3. We did not invent any.
\n\nIt’s easy to look at a 0-click exploit chain like the one we developed and see a unique technical feat, when what it really reveals is capabilities currently available to many attackers.
Natalie Silvanovich, Project Zero, 14 January 2026
Read this in two voices
\n- If you buy phones: this is why a Moderate decoder bug plus a Moderate driver bug is still a 0-click to root.
- If you write Android: verify mitigations per release, not per design doc. AOSP having a seccomp file is not the same as Pixel loading it.
- If you write codecs: impact is the maximum an attacker can get, not the crash you see in QA. Apple’s -fbounds-safety is the existence proof.
Audio Attack Surface
\nThe Dolby Unified Decoder is 0-click on most Android phones because Google Messages transcribes incoming audio before anyone taps the thread. On Pixel 9 a second process, com.google.android.tts, also decodes incoming audio. P0 is not fully sure why; it appears to be about making messages searchable. Both processes offer the file to every decoder on the device, including UDC, which most OEMs integrate. The bulk of real messages use a handful of formats. Incoming RCS/SMS almost certainly does not contain Dolby Digital / DD+. Android does not ship encoders for those formats. They live in movies and TV. Taking UDC and other rare codecs off the 0-click path would have blocked the worst outcome of CVE-2025-54957 without waiting for Dolby’s blob.
AI features are expanding that path on purpose. Transcription, search, on-device summaries all want decode-before-open. Sometimes the user benefit is real. Vendors still have to notice when a feature quietly adds remote-reachable code. P0’s ask is ongoing review of 0-click and 1-click surface plus deliberate decisions, not accidental surface growth.
\ncom.google.android.tts on Pixel 9 is another. Allow-list the formats you will actually receive. Deny UDC, Monkey’s Audio, and the long tail until a user presses Play in a player. That is a product decision, not a CVE.| Decoder on the 0-click path | Why it is there | P0’s cut |
|---|---|---|
| Common capture formats (AAC, AMR, etc.) | Real voicemail / RCS voice notes | Have to live here; fuzz and sandbox hard |
| Dolby UDC (AC-3 / E-AC-3) | OEM blob, all decoders offered to Messages/TTS | Remove from auto-transcribe; no Android encoder, commercial media |
| Other rare codecs | Same all-decoders habit | Same cut. CVE-2025-49415 Monkey’s Audio was the appetizer |
| com.google.android.tts | Searchability of incoming audio on Pixel 9 | Document it; it is a second 0-click decoder process |
Bug Discovery Time Frames
\nThe surprise was speed. Project Zero looked at Dolby UDC in a one-week team hackathon. Ivan Fratric had CVE-2025-54957 in under two days. Seth Jenkins had CVE-2025-36934 in under one day of reading BigWave. That sentence is easy to misuse, so Silvanovich immediately subtracts the setup: about three weeks of codec entry-point work and debug tooling before the hackathon, about four weeks to build DriverCartographer before the driver read, and mixed results on other audio codecs first.
\nEven with that tax, the time to the bugs is small next to the impact, especially the LPE. A lot of the UDC investment is one-time and pays for the next codec. P0’s estimate: a well-resourced attacker can measure a 0-click Android chain in person-weeks, not person-years.
\n
Android has paid for codec security: VRPs, OSS-Fuzz. This particular UDC bug was unlikely to fall out of fuzzing, and as far as P0 knows Pixel’s fuzzing does not cover UDC at all. Attack-surface amnesia is a recurring 0-click source. Heavily locked components still have bugs; attackers prefer the rooms nobody listed. The prescription is a rigorous 0-click map plus fuzz and review that actually includes the blobs OEMs shipped.
\nDrivers remain a soft target. The series cites the same P0 driver canon as Part 2: Driving Forward, Qualcomm DSP, ITW Android. Android and upstreams (Samsung, Qualcomm, ARM, Imagination) have moved; attackers have moved faster. GTIG has detected and reported 16 Android driver vulnerabilities used in the wild since 2023. P0’s menu, all likely necessary: rewrite the worst drivers in managed languages (Rust), consistent review of new drivers, less access from unprivileged/constrained contexts, and drivers that can actually be updated on the device.
\nEase of Exploitability
\nEstimates from the people who wrote the chain: about eight person-weeks to exploit the UDC bug as used here, about three weeks for a basic BigWave proof-of-concept. That is not a lot of time for what the chain buys. Android mitigations did raise the bill. Two advertised protections did not show up.
\nThe seccomp file that Pixel 9 did not load
\nThe Dolby process on Pixel 9 had no seccomp policy. The policy exists in AOSP and was enforced on several other Android 16 devices P0 tested. Had Pixel 9 loaded it, Silvanovich estimates at least one extra person-month on the userland exploit. Security features only work if someone checks they are on, ideally every release. Otherwise you ship a regression and call it a sandbox.
\n
kASLR that has not worked since 2016
\nkASLR is not effective on Pixel, for a reason known since 2016 and written up in Jenkins’s November 2025 post. Android and Linux both deprioritized the work that would have restored it. That choice made BigWave easier. P0 estimates roughly six extra weeks with working kASLR — and with that extra, they might not have pursued the driver bug at all.
\nApple compiled the same blob differently
\nP0 has not successfully exploited the UDC bug on Mac or iPhone. Those builds use -fbounds-safety, which injects a bounds check that stops the OOB write. Dolby should ship that class of compiler protection on every platform, not only the one that asked. Apple also shipped MIE, hardware memory protection in the MTE family, on new devices. MIE would not have stopped UDC without -fbounds-safety, because UDC’s custom evo heap is not the tagged allocator — but it would probabilistically hinder a BigWave-shaped kernel bug on iOS.
\nPixel 8 onward shipped MTE. It is off except for users who opt into Advanced Protection. Apple paid the money and the performance and it showed, on this chain, for both the decoder and a hypothetical kernel cousin. Android could do the same for more than the opt-in cohort.
\nTwo bugs to kernel, which is a sandboxing tell
\nThe chain is short. Kernel privileges from 0-click needed two software defects. Platforms with real sandbox ladders force longer chains: more contexts, more bugs. That is a hint. Android could still reduce what media decode processes are allowed to be. Part 2 already named the AV1 node. Part 3 says the pattern, not just the node.
\n
0xffffff8000010000 still names .data, do not claim kASLR in the threat model. MTE default-on is a product fight; this post is evidence for the fight.Patch Timeframe
\nBoth bugs were public and unfixed on Pixel for a stretch. Calendar from the post:
\n| Date | UDC (CVE-2025-54957) | BigWave (CVE-2025-36934) |
|---|---|---|
| 2025-06-20 | — | Reported to Pixel; rated Moderate |
| 2025-06-26 | Reported to Dolby | — |
| 2025-09-18 | ChromeOS gets first binary fixes | Severity raised to High |
| 2025-09-19 | — | Public after 90 days (P0 policy) |
| 2025-10-08 | Pixel receives Dolby binaries | — |
| 2025-10-15 | Public after 30-day adopt window | — |
| 2025-11-12 | Samsung first mobile patch (Critical) | — |
| 2026-01-05 | Pixel ships UDC | — |
| 2026-01-06 | — | Pixel ships BigWave |
Silvanovich calls 139 days for a 0-click-capable bug to reach any Android phone alarming, and Pixel’s extra 54 days worse. The UDC bug was public for 82 days before Pixel patched. Disclosure followed P0’s policy (30-day adoption after a vendor had a binary for UDC; 90 days for BigWave).
\nWhat Dolby told integrators
\nOne cause of the slow fix was likely Dolby’s advisory (14 Oct 2025). P0 told Dolby the issue was highly exploitable when they filed, and sent status including exploit technical detail as the work progressed. The advisory still said:
\n\nWe are aware of a report found with Google Pixel devices indicating that there is a possible increased risk of vulnerability if this bug is used alongside other known Pixel vulnerabilities. Other Android mobile devices could be at risk of similar vulnerabilities.
Dolby Security Advisory CVE-2025-54957, as quoted in Part 3
P0: that is not an accurate risk assessment. Part 1 showed the bug is exploitable on its own, with no extra bugs, for code execution in the UDC process. Dolby is probably thinking of the extra bug needed to leave mediacodec. Almost every modern memory bug needs a next hop. P0 also told them exploit vendors already have kernel LPEs on most Android devices. No other vendor in P0’s experience describes sandboxed code execution as requiring the bug to be “used alongside other known […] vulnerabilities.”
\nThe advisory also said:
\n\nFor other device classes, we believe the risk of using this bug maliciously is low and the most commonly observed outcome is a media player crash or restart.
Dolby Security Advisory CVE-2025-54957, as quoted in Part 3
P0: that understates risk on other platforms. Even GTIG cannot honestly score “will attackers use this” per bug. “Most commonly observed outcome is a crash” is true of the worst memory bugs; that is why serious teams rate the maximum access, not the modal QA symptom. Except on Apple, where UDC is built with -fbounds-safety, this bug is code execution in whatever context runs UDC. Impact still depends on how you sandbox it — a smart TV with trusted streams is not Messages auto-transcribe — but that does not make the primitive a crash. Integrators should have been given the maximum and allowed to decide.
\nModerate versus Critical
\n
What Dolby told Android and Pixel is unclear. Android’s priority matrix is public. mediacodec is a constrained context per queue hardening (2019), so at report time the UDC bug was “remote arbitrary code execution in a constrained context” = Moderate. Samsung rated the same bug Critical. Android told P0 they have since updated the matrix; future bugs of this type will be Critical.
\nBigWave was reported to Pixel 20 June 2025 and also started at Moderate. The matrix’s base for “local ACE in a privileged context / bootloader / TEE / kernel” is High, then the modifier “requires running as a privileged context” was applied. The modifier text says privileged; P0’s experience is that it gets used for anything not directly reachable from unprivileged apps, including constrained contexts like mediacodec. Severity became High on 18 September 2025. The fix reached devices 6 January 2026. P0 published after 90 days, on 19 September 2025.
\nVendors disagree on philosophy. Some raise 0-click entrypoints. Some raise the sandboxes around them. Both can work. What does not work is deprioritizing every link so that a two-bug 0-click to kernel is Moderate plus Moderate. Someone in the chain has to be High/Critical or users do not get a patch clock that matches the risk.
\nDiffusion of responsibility is normal in vulnerability management: each hop looks smaller than the movie. Codec vendors treat memory safety as the platform’s problem; platforms treat the supply chain as if it will be clean. Teams with the best posture assume every external blob is already compromised and build for that day. That stance is what makes chains long. That is what protects people.
\nPatch Propagation
\nEven after Pixel patched UDC, the rest of Android is on a slower clock. Carrier approval, OEM cadence, devices that never get another bulletin. Android can bypass some of that for selected system libraries via APEX — Google-signed modules through Play, faster cycle. UDC does not ship as part of Android, so it is not an APEX. Making it one would take licensing and ownership changes P0 flags as significant, not a weekend flag flip.
\nA CISO-length reading of diffusion of responsibility
\nThree companies sat on the same 0-click. Dolby owned the blob and wrote an advisory that framed sandboxed ACE as a Pixel-combo issue and a crash elsewhere. Android owned the matrix that called remote ACE in mediacodec Moderate, and the modifier that pulled a kernel driver down from High. Pixel owned the device that did not load AOSP seccomp, did not have working kASLR, did not fuzz UDC, and shipped 82 public days late on the decoder. Samsung, not in the exploit screenshots, rated Critical and patched mobile first.
\nNone of those sentences is a morality play. They are a map of who has to move. Codec vendors: maximum impact, compiler flags on all SKUs, faster binaries to every integrator. Platforms: assume the blob is on fire; rate the landing zone like a landing zone; verify mitigations on the flagship you actually ship. OEMs: the 0-click map includes TTS and every decoder Messages will feed. Play/APEX for the bits you do not want stuck behind carriers.
\n- Name the 0-click map once a year. If a process transcribes or indexes mail, its decoders are on the map.
- Fail CI if advertised sandboxes (seccomp, MTE, kASLR claims) are off on the user build.
- Rate so that at least one bug in a two-hop 0-click is Critical/High with a clock.
- Give integrators the unconstrained primitive, not the QA crash.
- Budget Rust, review, reduced access, and updatability for SoC drivers — GTIG’s 16 ITW driver bugs since 2023 are the backlog.
How to read Parts 1–3 as one argument
\n| Post | What it proved | What Part 3 does with it |
|---|---|---|
| Part 1 (Natalie) | UDC is 0-click ACE in mediacodec via Messages | Pull rare codecs off that path; -fbounds-safety works; seccomp was missing |
| Part 2 (Seth) | mediacodec can LPE through /dev/bigwave | Drivers are still soft; kASLR skip; shorten the sandbox ladder |
| Part 3 (Natalie) | The calendar, the matrix, the advisory | Stop rating both hops Moderate; stop waiting 139 days |
The technical recommendations in 1 and 2 — ASLR low bits, scudo checksums, /proc/self/mem, lifetime of fd-bound jobs — still stand. Part 3 says they are necessary and not sufficient if the surface should not have included UDC, if the mitigation was not on, and if the patch clock was Moderate.
\nKey Takeaways
\n- Messages (and Pixel TTS) decode incoming audio with every decoder, including cinema-format UDC that almost never arrives in a text message.
- Find cost after setup: days. Exploit cost: ~8 weeks UDC, ~3 weeks BigWave PoC. Well-resourced attackers: person-weeks.
- Pixel 9 skipped AOSP mediacodec seccomp (other Android 16 devices had it). kASLR on Pixel has been ineffective since 2016.
- Apple’s UDC with -fbounds-safety: not exploited. MTE on Pixel is opt-in Advanced Protection only.
- Two bugs to kernel means the media sandbox is too privileged. GTIG: 16 ITW Android driver vulns since 2023.
- UDC: 139 days to any Android phone patch; Pixel 54 days slower; 82 days public. Samsung Critical and first.
- Dolby’s advisory understated a standalone ACE primitive. Android’s matrix called it Moderate; that bucket is now Critical.
- Rate at least one hop in a 0-click chain High/Critical. Assume external blobs are compromised. APEX cannot yet carry UDC.
Defensive Recommendations
\n- Cut surface. Auto-transcribe only formats you will actually receive. Keep UDC and the long tail for explicit Play in a player.
- Map processes. Messages plus
com.google.android.ttsplus anything else that decodes inbound mail. Document them. - Verify mitigations every release. seccomp on mediacodec, kASLR actually random, MTE policy. AOSP files are not evidence.
- Compiler. Demand -fbounds-safety (or equivalent) on OEM media blobs for Android SKUs, not only Apple.
- Priority. 0-click entry or its sandbox must be High/Critical. Do not Moderate both. Do not hide kernel bugs behind a constrained-context modifier if that context is the 0-click landing zone.
- Vendors of blobs. Advisory text = maximum primitive. Crash-as-impact is not a rating. Ship binaries to all integrators on the same clock.
- Drivers. Rust where it hurts, review new nodes, drop access from decode contexts, make them updatable. Sixteen ITW driver bugs is a program, not a coincidence.
- Updates. January 2026 SPL on Pixel is necessary and not sufficient for the rest of Android. Track blob hashes. Push the APEX conversation for third-party codecs.
Conclusion
\nP0’s last page is the one that should outlive the gadgets. This chain was not a magic trick. It was a rare codec on the voicemail path, a driver the sandbox is supposed to open, a seccomp file nobody loaded, a KASLR story from 2016, a Moderate rating, and a calendar. Most people alive now keep their privacy, money, and sometimes their safety in a phone. The mitigations exist. The patch trains exist. Vendors should treat memory corruption as a platform problem even when the bytes came from someone else’s blob, and they should get patches to users on a clock that matches a 0-click, not a crash in QA.
\nOriginal text: "A 0-click exploit chain for the Pixel 9 Part 3: Where do we go from here?" by Natalie Silvanovich at Google Project Zero.


