Security1 publisher2 min readPublished
Signed int arithmetic in libde265 shrinks a 4 GB plane allocation to 1,040 bytes before the fill
The proof of concept in strukturag's advisory declares a 33800 by 63520 picture at 16-bit depth, wraps the signed size calculation, and lets fill_plane write 4,294,968,336 bytes into the undersized heap buffer.
The Watch · Security desk

What happened
- A GitHub security advisory for strukturag/libde265 reports a heap buffer overflow in de265_image_get_buffer, reached through the SPS dimensions of a crafted H.265 bitstream at 16-bit depth.
- Triggering it takes a crafted file opened by any application that uses libde265, and an unauthenticated, unprivileged attacker can do it.
- The SPS parser accepts picture dimensions up to 65535 and bit depths up to 16, and the proof of concept's 33800 by 63520 picture at 16 bits clears every front-end validation check.
- AddressSanitizer records a write of 4,294,968,336 bytes against a 1,040-byte heap region, preceded by an undefined-behaviour sanitizer report on the signed multiplication.
- The advisory names libde265 v1.0.19 at commit 824b413, the current HEAD of master, as the affected version.
Compiled by The WatchSomething wrong?How this is made
Why it matters
- constraint No patched version is listed, so anyone shipping libde265 has to carry the size_t change locally or cap declared frame dimensions upstream of the decoder.
- capability Anyone can reproduce the crash without knowing how an HEVC bitstream is laid out: the advisory hands over a generator and a ready-made input, so every downstream triage queue starts with a working trigger.
- contradiction The advisory scores this at CVSS 8.8 on high code execution potential, while the artefact it publishes demonstrates a sanitizer-caught crash.
- decision The same disclosure includes a second out-of-bounds write, in process_reference_picture_set. Teams decoding untrusted video now have two header-parsing write bugs to weigh when deciding whether decode runs in its own process.
The bug comes down to a type mismatch. de265_image_get_buffer sizes its plane allocation with signed int arithmetic on luma_height * luma_bpl, while fill_image computes the same quantity in size_t [6]. The overflow lands at libde265/image.cc:128 [2]. With the proof of concept's dimensions, stride alignment to 16 bytes puts luma_bpl at 67616 bytes, the signed product 63520 * 67616 at 4,294,968,320, and the wrap at 1024; the allocator adds 16 and returns 1,040 bytes [9]. The wrap leaves only the excess over 2^32 [1].
Then the fill runs. fill_plane writes 4,294,968,336 bytes into that region [10], which is 4,294,967,296 bytes past its end, exactly 4 GiB [2].
A filter that enforces the format's own ranges on incoming bitstreams passes this file through. The advisory's suggested fix is size_t, or at minimum overflow-checked arithmetic, for all plane size computations in de265_image_get_buffer, plus rejecting SPS dimensions where the true plane size would exceed a reasonable limit [14].
The write is a linear plane fill, and 4 GB of it will reach unmapped pages long before it finishes in most address spaces, so plan for an attacker-triggered crash of the decoder process. The advisory documents that crash: a signed integer overflow report from the undefined-behaviour sanitizer, then AddressSanitizer's heap-buffer-overflow write. It stops short of a code execution exploit [17]. The generator it publishes patches the SPS NAL of girlshy.h265, a seed from libde265's own test data [15].
What to watch
- Packagers need a commit in master moving the plane size computation to size_t, or a tagged release carrying it, before they can ship a fix.
- Whether the separately reported out-of-bounds write in process_reference_picture_set gets its own advisory and reproducer.
- Whether downstream projects that link libde265 publish their own advisories once the trigger file circulates.