CVE Tools
Back to blog

PixelSmash: one video file that puts FFmpeg-powered servers at risk

CVE-2026-8461 is a patched heap overflow in FFmpeg's MagicYUV decoder — reliable DoS, conditional RCE, and hiding in software you didn't know shipped FFmpeg.

FFmpeg's libavcodec is the quiet engine behind a staggering amount of the internet's media handling — media servers, file-sync previews, desktop thumbnailers, NAS boxes, and AI data pipelines all lean on it. So when JFrog disclosed CVE-2026-8461, nicknamed "PixelSmash," a heap out-of-bounds write in FFmpeg's MagicYUV decoder, the bug itself was ordinary but the blast radius was not.

Here's the honest version: it's a reliable denial-of-service against anything that auto-decodes untrusted video, and a conditional remote-code-execution in the wrong (but common enough) conditions. It is not on CISA's KEV list, EPSS is low (~0.4%), and there's no public weaponized exploit as of this writing. The real work isn't deciding whether to patch — it's finding every embedded copy of FFmpeg.

What actually breaks

MagicYUV is a fast lossless codec whose decoder splits each frame into horizontal slices. The flaw is a rounding mismatch: with chroma-subsampled formats (like YUV420P), the frame allocator and the per-slice decoder compute the chroma plane height differently. Feed the decoder an odd slice_height and the second slice's write base lands exactly one row past the heap buffer — a classic out-of-bounds write (CWE-787).

Because the overflowing bytes are attacker-controlled pixel data, this isn't only a crash. The bytes after the buffer can include an AVBuffer struct; overwrite its free function pointer and its argument, and FFmpeg's normal frame cleanup (av_buffer_unref()) turns into an attacker-controlled call. That's the path from "out-of-bounds write" to "code execution."

Why it's a big deal: FFmpeg is everywhere

The trigger is a crafted AVI, MKV, or MOV (notably not plain MP4) carrying a MagicYUV stream. The CVSS vector carries UI:R — "user interaction required" — but for server-side targets that interaction is usually an automatic background decode, not a human pressing play. JFrog reported crashes or RCE potential across a wide set of software:

  • Self-hosted media servers — Jellyfin (RCE demonstrated via the automatic library scan), Emby, Kodi.
  • File / collaboration platforms that auto-generate previews — Nextcloud, Immich, PhotoPrism.
  • Desktop thumbnailersffmpegthumbnailer used by GNOME / KDE / XFCE file managers.
  • NAS appliances — Synology DSM, QNAP — and AI/ML pipelines via PyAV, OpenCV, NVIDIA DALI, Hugging Face Datasets.
  • Plex was reported safe — because it builds FFmpeg with an allow-list of only the decoders it needs. That's the reusable lesson, not luck.

The attack chain

From file to impact, with the two outcomes that actually matter — crash versus code execution — and where each is decided:

PixelSmash: from a crafted video to code execution

  1. Crafted MagicYUV file — A ~50 KB **AVI / MKV / MOV** carrying a MagicYUV stream with an odd `slice_height`. (Not plain MP4.)
  2. Auto-decoded — An upload or library scan makes Jellyfin / Nextcloud / a thumbnailer **decode it automatically** — `UI:R`, but no human click needed.
  3. Heap out-of-bounds write — An allocator-vs-decoder rounding mismatch writes **one chroma row past** the heap buffer (CWE-787).
  4. ASLR off / chained leak? — Reliable RCE was only demonstrated with **ASLR disabled** or by chaining a separate info-leak.
  5. Crash (DoS) — On a hardened, ASLR-on host the realistic outcome is a **decoder/worker crash** — denial of service.
  6. RCE as the decoder's user — Overwrite an adjacent `AVBuffer` free pointer → `av_buffer_unref()` makes an **attacker-controlled call** (e.g. `system()`). Mitigation: upgrade to 8.1.2+ and sandbox the transcoder.

Am I exposed?

Exposure here is an inventory problem, not a network scan — there's no endpoint to probe. Check whether the vulnerable decoder is present, then map the libavcodec version that each application actually ships (the OS package update does not fix copies bundled inside apps):

# Is the vulnerable decoder compiled in?
ffmpeg -decoders 2>/dev/null | grep magicyuv     # "VFS..D magicyuv" = present
ffmpeg -version                                  # program + libavcodec version (fixed: 8.1.2)

# Read the version out of a bundled / stripped binary (no CLI on PATH):
strings /usr/lib/*/libavcodec.so.* | grep -iE 'Lavc|libavcodec version'
# NOTE: the .so soname major (e.g. .61) is NOT enough — confirm major.minor.micro vs 8.1.2

Gate untrusted uploads at the door: run ffprobe and quarantine anything whose codec_name is magicyuv before it reaches a vulnerable decoder. A clean result on one host does not prove your whole estate is safe — bundled copies are the long tail.

Fix it

  1. Upgrade libavcodec to FFmpeg 8.1.2+ (or your distro's patched build) everywhere it lives — including the copies bundled inside Jellyfin (jellyfin-ffmpeg), Emby, Electron apps, container images, and NAS firmware. The OS package update misses those.
  2. Can't upgrade yet? Rebuild with --disable-decoder=magicyuv (MagicYUV is rarely needed), or adopt an allow-list of only the decoders you use — the approach that kept Plex safe.
  3. Sandbox the transcoder — dedicated low-priv user, container, seccomp/AppArmor, and keep ASLR on. That turns a successful overflow from RCE into a contained crash.
  4. Gate ingestffprobe-and-reject MagicYUV on untrusted uploads, independent of patch state.

FAQ

Is CVE-2026-8461 being exploited in the wild?
No public evidence of in-the-wild exploitation as of late June 2026, and it is not on CISA's KEV list. All known exploitation is JFrog's lab demonstration.
Is it remote code execution or just a crash?
Both, conditionally. A denial-of-service crash is highly reliable. Full RCE was only demonstrated with ASLR disabled or by chaining a separate info-leak — on a hardened host the realistic outcome is a crash.
How do I fix it?
Upgrade libavcodec to FFmpeg 8.1.2 or later — and critically, update the FFmpeg bundled inside your apps (Jellyfin, Emby, NAS firmware), not just the OS package. If you can't patch, disable the magicyuv decoder.
Which file types trigger it?
A crafted AVI, MKV, or MOV carrying a MagicYUV video stream — notably not a plain MP4.