core-jmp core-jmpdeath of core jump

A 0-click Exploit Chain for the Pixel 9, Part 3: Where Do We Go From Here?

Natalie Silvanovich’s Part 3: the Pixel 9 0-click was person-weeks, not a miracle. Rare codecs on transcription, missing seccomp, kASLR dead since 2016, a Moderate rating, 139 days to any Android UDC patch. Samsung called it Critical. Android has moved that bucket. Assume the blob is on fire.

oxfemale September 15, 2026 19 min read 49 reads
Export PDF
A 0-click Exploit Chain for the Pixel 9, Part 3: Where Do We Go From Here?
Original text: "A 0-click exploit chain for the Pixel 9 Part 3: Where do we go from here?"Natalie Silvanovich, Google Project Zero (14 January 2026). Sequel to Part 1 and Part 2. Dolby advisory sentences below are reproduced verbatim. The source post has no figures or code listings; diagrams here are ours, dated from the original calendar.
\n
Unopened phone message with unused film-reel codec canisters in the background
The voicemail is still unopened. The rare cinema codec was on the photocopier anyway.
\n
A wall calendar with many days crossed between reported and patched
Kitchen: 139 days from Dolby report to any Android phone patch. Pixel took 54 more.
\n
Dated timeline of UDC and BigWave reports, disclosure, and patches
Calendar compiled from Part 3. Dates: original article.
\n

Executive Summary

\n

Parts 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.

\n

This 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

It’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
\n
Kitchen table: Parts 1 and 2 showed how the basement photocopier and the loading-dock forklift work. Part 3 asks why the rare cinema codec was even on the incoming-mail path, why the safety guard was missing on this assembly line, and why the calendar between alarm and repair had so many pages.
\n
For operators: If you only file tickets from this post: (1) pull unused codecs off 0-click decode, (2) test seccomp and kASLR on every build, (3) rate 0-click entry or the sandbox around it High/Critical, never both Moderate, (4) treat supply-chain blobs as already compromised.
\n

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.
\n

Audio Attack Surface

\n

The 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.

\n

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.

\n
Kitchen table: You do not need a cinema codec to transcribe a voicemail. Leaving the cinema projector plugged into the incoming-mail photocopier is how a movie-format bug becomes a text-message bug. The second machine labeled TTS is a second photocopier nobody fully documented. Two photocopiers, one rare format, no tap required.
\n
For operators: Hunt: which processes call Codec2/soft decoders on incoming RCS attachments? Messages is one. com.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.
\n
Decoder on the 0-click pathWhy it is thereP0’s cut
Common capture formats (AAC, AMR, etc.)Real voicemail / RCS voice notesHave to live here; fuzz and sandbox hard
Dolby UDC (AC-3 / E-AC-3)OEM blob, all decoders offered to Messages/TTSRemove from auto-transcribe; no Android encoder, commercial media
Other rare codecsSame all-decoders habitSame cut. CVE-2025-49415 Monkey’s Audio was the appetizer
com.google.android.ttsSearchability of incoming audio on Pixel 9Document it; it is a second 0-click decoder process
Surface cut compiled from Part 3. Source: original article; table is ours.
\n

Bug Discovery Time Frames

\n

The 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.

\n

Even 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
Table of P0 person-week estimates versus missing mitigations
Find time in days; exploit time in weeks; missing seccomp and kASLR in extra months. Numbers: original article.
\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.

\n

Drivers 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.

\n
Kitchen table: Finding the photocopier bug took two days after three weeks of learning where the paper goes. Finding the forklift bug took one day after four weeks of building a map of every chute from the mailroom. That is not “easy.” It is “cheap compared to what the keys open.” A well-funded crew does not need a decade. They need weeks.
\n
For operators: If your threat model is “nation-state only”: P0 is telling you the find cost is person-weeks once the surface is named. If your fuzzing dashboard is green: ask whether UDC and every other OEM blob on the transcription path are even in the corpus. Pixel’s, per this post, was not.
\n

Ease of Exploitability

\n

Estimates 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.

\n

The seccomp file that Pixel 9 did not load

\n

The 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
Two phone assembly lines; one machine is missing its safety guard
Kitchen: the neighboring line had the guard. This Pixel 9 line did not, even though the guard is in the parts catalog (AOSP).
\n

kASLR that has not worked since 2016

\n

kASLR 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.

\n

Apple compiled the same blob differently

\n

P0 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.

\n

Pixel 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.

\n

Two bugs to kernel, which is a sandboxing tell

\n

The 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
Two keys on a table: front door and inner sandbox door
Kitchen: you can harden the front door (0-click entry) or the inner door (sandbox). If you rate both Moderate, nobody changes the locks.
\n
Kitchen table: The catalog listed a safety guard (seccomp) and a randomized street number (kASLR). One line of phones shipped without the guard. The street number has been painted on the east fence since 2016. Apple put a ruler on the photocopier (-fbounds-safety) so the overflowing roast cannot leave the tray. Same Dolby machine, different compiler flag, no Part 1.
\n
For operators: Release gate: dump mediacodec seccomp from a live Pixel, compare to AOSP policy, fail the build if empty. Dump kASLR entropy / linear-map alias; if 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.
\n

Patch Timeframe

\n

Both bugs were public and unfixed on Pixel for a stretch. Calendar from the post:

\n
DateUDC (CVE-2025-54957)BigWave (CVE-2025-36934)
2025-06-20Reported to Pixel; rated Moderate
2025-06-26Reported to Dolby
2025-09-18ChromeOS gets first binary fixesSeverity raised to High
2025-09-19Public after 90 days (P0 policy)
2025-10-08Pixel receives Dolby binaries
2025-10-15Public after 30-day adopt window
2025-11-12Samsung first mobile patch (Critical)
2026-01-05Pixel ships UDC
2026-01-06Pixel ships BigWave
Compiled from Part 3. 139 days to any Android UDC patch; Pixel 54 days behind that; UDC public 82 days before Pixel shipped. Source: original article.
\n

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).

\n

What Dolby told integrators

\n

One 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

We 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
\n

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.”

\n

The advisory also said:

\n

For 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
\n

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.

\n

Moderate versus Critical

\n
Four panels: Android then, Samsung, Android now, BigWave modifier path
Same decoder bug: Android Moderate, Samsung Critical. Matrix later updated. Source: original article.
\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.

\n

BigWave 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.

\n

Vendors 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.

\n

Diffusion 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.

\n
Kitchen table: Dolby told the apartment building the photocopier only causes trouble if you already have a stolen master key, and that elsewhere it mostly just jams. Samsung treated the photocopier as a fire. Android treated it as a constrained-context Moderate until they moved the line. If both the front door and the inner door are “we’ll get to it,” the calendar grows extra pages.
\n
For operators: Priority rule P0 is actually stating: pick at least one of {0-click entry, isolating sandbox} and make bugs there High/Critical. Do not apply the “needs privileged context” modifier to mediacodec-reachable kernel bugs if mediacodec is the 0-click landing zone. When a codec vendor writes “used alongside other vulnerabilities,” demand the unconstrained primitive in the same paragraph.
\n

Patch Propagation

\n

Even 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.

\n
Kitchen table: The building’s own elevators can be serviced by the manufacturer overnight (APEX). The cinema projector in the basement belongs to another company, so the overnight crew is not allowed to touch it. Everyone else in the city waits for their landlord and their phone company to agree it is time.
\n
For operators: If you run a fleet: do not equate “Pixel January 2026 SPL” with “Android is done.” Ask OEMs for the UDC blob hash and the BigWave/VPU driver versions. If you work at Android: the APEX question for third-party codecs is a supply-chain negotiation, but this post is the security case for having the negotiation.
\n

A CISO-length reading of diffusion of responsibility

\n

Three 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.

\n

None 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
  1. Name the 0-click map once a year. If a process transcribes or indexes mail, its decoders are on the map.
  2. Fail CI if advertised sandboxes (seccomp, MTE, kASLR claims) are off on the user build.
  3. Rate so that at least one bug in a two-hop 0-click is Critical/High with a clock.
  4. Give integrators the unconstrained primitive, not the QA crash.
  5. Budget Rust, review, reduced access, and updatability for SoC drivers — GTIG’s 16 ITW driver bugs since 2023 are the backlog.
\n

How to read Parts 1–3 as one argument

\n
PostWhat it provedWhat Part 3 does with it
Part 1 (Natalie)UDC is 0-click ACE in mediacodec via MessagesPull rare codecs off that path; -fbounds-safety works; seccomp was missing
Part 2 (Seth)mediacodec can LPE through /dev/bigwaveDrivers are still soft; kASLR skip; shorten the sandbox ladder
Part 3 (Natalie)The calendar, the matrix, the advisoryStop rating both hops Moderate; stop waiting 139 days
Series spine. Source: original trilogy.
\n

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.

\n

Key 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.
\n

Defensive Recommendations

\n
  1. Cut surface. Auto-transcribe only formats you will actually receive. Keep UDC and the long tail for explicit Play in a player.
  2. Map processes. Messages plus com.google.android.tts plus anything else that decodes inbound mail. Document them.
  3. Verify mitigations every release. seccomp on mediacodec, kASLR actually random, MTE policy. AOSP files are not evidence.
  4. Compiler. Demand -fbounds-safety (or equivalent) on OEM media blobs for Android SKUs, not only Apple.
  5. 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.
  6. Vendors of blobs. Advisory text = maximum primitive. Crash-as-impact is not a rating. Ship binaries to all integrators on the same clock.
  7. 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.
  8. 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.
\n

Conclusion

\n

P0’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.

\n

Original 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.

oxfemale Vulnerability research, reverse engineering, and exploit development.
// Discussion