ANT-2026-PVN0XWJM · ffmpeg/ffmpeg

heap-buffer-overflow high

Severity Claude high · Security research firm high · Maintainer -

Discovered by Claude Mythos Preview

REPORT

Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Ada Logics.

ANT-2026-PVN0XWJM: Heap-buffer-overflow in copy_block.h:51

FFmpeg's AGM (Amuse Graphics Movie) decoder performs an out-of-bounds heap read while decoding inter-frame data. Inside decode_inter_plane, a source pointer passed to copy_block8 lands 32 bytes before the start of an allocated frame buffer, resulting in an 8-byte read from heap redzone memory. An attacker supplying a crafted AGM video file can trigger this condition, potentially leaking adjacent heap contents or crashing the decoding process.

Target

Project: ffmpeg
Location: copy_block.h:51

Technical Details

ASAN: "READ of size 8 at 0x7a507cbe00f0 ... located 32 bytes before 128-byte region". The source pointer computed in decode_inter_plane (agm.c:453) for the block copy is not clamped to the bounds of the reference frame buffer allocated via ff_get_buffer, so attacker-controlled offsets in the bitstream can drive the read off the front of the allocation.

Crash trace (truncated — full trace in attached crash.log):

INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2820721567
INFO: Loaded 1 modules   (67490 inline 8-bit counters): 67490 [0x64f633a3bef8, 0x64f633a4c69a), 
INFO: Loaded 1 PC tables (67490 PCs): 67490 [0x64f633a4c6a0,0x64f633b540c0), 
/out/ffmpeg_AV_CODEC_ID_AGM_fuzzer: Running 1 inputs 1 time(s) each.
Running: /tmp/poc
EXIT_CODE:1


=== ASAN Report ===
=================================================================
==27==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7a507cbe00f0 at pc 0x64f6332f42e4 bp 0x7ffda6775660 sp 0x7ffda6775658
READ of size 8 at 0x7a507cbe00f0 thread T0
    #0 0x64f6332f42e3 in copy_block8 /src/ffmpeg/libavcodec/copy_block.h:51:9
    #1 0x64f6332f42e3 in decode_inter_plane /src/ffmpeg/libavcodec/agm.c:453:21
    #2 0x64f6332ec6c5 in decode_inter /src/ffmpeg/libavcodec/agm.c:883:11
    #3 0x64f6332e963f in decode_frame /src/ffmpeg/libavcodec/agm.c:1198:19
    #4 0x64f63330313a in decode_simple_internal /src/ffmpeg/libavcodec/decode.c:444:16
    #5 0x64f63330313a in decode_simple_receive_frame /src/ffmpeg/libavcodec/decode.c:604:15
    #6 0x64f63330313a in ff_decode_receive_frame_internal /src/ffmpeg/libavcodec/decode.c:640:15
    #7 0x64f633305180 in decode_receive_frame_internal /src/ffmpeg/libavcodec/decode.c:658:15
    [... 27 more frames — full trace in crash.log]

Reproduction

  1. Construct an AGM bitstream whose inter-frame coding parameters produce a negative/out-of-range source offset in decode_inter_plane
  2. Deliver the file to the victim (upload, attachment, stream, thumbnailer, etc.)
  3. Decoder calls copy_block8 with a source pointer pointing before the reference frame buffer

[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]

Acknowledgement

This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-PVN0XWJM.


Reference: ANT-2026-PVN0XWJM
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure

SECURITY RESEARCH FIRM ANALYSIS

Triage and disclosure were performed by Ada Logics.

Verdict
true positive
Severity
high
UPSTREAM FIX

The change that resolved this finding.

diff --git a/libavcodec/agm.c b/libavcodec/agm.c
index c13b4d963e68d..5d27d17274c09 100644
--- a/libavcodec/agm.c
+++ b/libavcodec/agm.c
@@ -409,12 +409,14 @@ static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size,
                 int map = s->map[x];
 
                 if (orig_mv_x >= -32) {
-                    if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h ||
-                        x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w)
+                    int src_y = (s->blocks_h - 1 - y) * 8 - mv_y;
+                    int src_x = x * 8 + mv_x;
+                    if (src_y < 0 || src_y + 8 > h ||
+                        src_x < 0 || src_x + 8 > w)
                         return AVERROR_INVALIDDATA;
 
                     copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
-                                prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x),
+                                prev->data[plane] + src_y * prev->linesize[plane] + src_x,
                                 frame->linesize[plane], prev->linesize[plane], 8);
                     if (map) {
                         s->idsp.idct(s->wblocks + x * 64);
@@ -446,12 +448,14 @@ static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size,
                     return ret;
 
                 if (orig_mv_x >= -32) {
-                    if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h ||
-                        x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w)
+                    int src_y = (s->blocks_h - 1 - y) * 8 - mv_y;
+                    int src_x = x * 8 + mv_x;
+                    if (src_y < 0 || src_y + 8 > h ||
+                        src_x < 0 || src_x + 8 > w)
                         return AVERROR_INVALIDDATA;
 
                     copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8,
-                                prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x),
+                                prev->data[plane] + src_y * prev->linesize[plane] + src_x,
                                 frame->linesize[plane], prev->linesize[plane], 8);
                     if (map) {
                         s->idsp.idct(s->block);

https://github.com/FFmpeg/FFmpeg/commit/45278542816cab5e8dcb120f9bd62e43ab2857bd

TIMELINE

Dates from discovery through public reveal.

  1. 2026-03-24 Reported to tracker
  2. 2026-05-28 Sent to maintainer
  3. 2026-06-06 Maintainer acknowledged
  4. 2026-06-11 Patch released
  5. 2026-08-17 Publicly revealed
PROVENANCE

SHA-3-512 hash:

3eec53da3e43eec5aff2839722a3f771bd90657c607d1e9d00fe7d83125512881e9024d6ae9d5d2f9f0252f02648977d5e79af4bd2254a1604bc999d39855d39

Committed 2026-05-28 07:58 PT

Revealed 2026-08-17 16:28 PT

Verify (download preimage.json)

Show preimage JSON
{
  "ant_id": "ANT-2026-PVN0XWJM",
  "bug_class": "Heap-buffer-overflow",
  "claude_severity": "high",
  "commit_sha": null,
  "created_at": "2026-03-24T18:32:18+00:00",
  "description": "FFmpeg's AGM (Amuse Graphics Movie) decoder performs an out-of-bounds heap read while decoding inter-frame data. Inside decode_inter_plane, a source pointer passed to copy_block8 lands 32 bytes before the start of an allocated frame buffer, resulting in an 8-byte read from heap redzone memory. An attacker supplying a crafted AGM video file can trigger this condition, potentially leaking adjacent heap contents or crashing the decoding process.",
  "discovered_at": null,
  "location": "copy_block.h:51",
  "poc_sha256": null,
  "preimage_version": 1,
  "project": "ffmpeg",
  "reproduction": [
    "1. Construct an AGM bitstream whose inter-frame coding parameters produce a negative/out-of-range source offset in decode_inter_plane",
    "2. Deliver the file to the victim (upload, attachment, stream, thumbnailer, etc.)",
    "3. Decoder calls copy_block8 with a source pointer pointing before the reference frame buffer"
  ],
  "technical_details": "ASAN: \"READ of size 8 at 0x7a507cbe00f0 ... located 32 bytes before 128-byte region\". The source pointer computed in decode_inter_plane (agm.c:453) for the block copy is not clamped to the bounds of the reference frame buffer allocated via ff_get_buffer, so attacker-controlled offsets in the bitstream can drive the read off the front of the allocation.",
  "title": "Heap-buffer-overflow in copy_block.h:51",
  "vendor_severity": "high"
}