Skip to content

droidvdec: fix segfault decoding NV12 semi-planar frames - #87

Open
Michal-Szczepaniak wants to merge 1 commit into
sailfishos:masterfrom
Michal-Szczepaniak:fix/decoder-stride-slice-height
Open

droidvdec: fix segfault decoding NV12 semi-planar frames#87
Michal-Szczepaniak wants to merge 1 commit into
sailfishos:masterfrom
Michal-Szczepaniak:fix/decoder-stride-slice-height

Conversation

@Michal-Szczepaniak

Copy link
Copy Markdown
Contributor

gst_droidvdec_convert_yuv420_semi_planar_to_i420() and gst_droidvdec_convert_yuv420_packed_semi_planar_to_i420() computed the source Y/UV plane pointers from hardcoded alignment guesses (stride aligned to 128, slice height aligned to 32/16) instead of the actual buffer layout, and never checked those pointers against the size of the buffer droidmedia handed over. When a decoder's real output geometry doesn't match the guess, this reads out of bounds and segfaults.

Use the stride/slice_height now reported by droid_media_codec_get_output_info() when available, falling back to the previous alignment guess otherwise, and bounds-check the computed frame size against DroidMediaData::size before touching the buffer so a bad guess or undersized buffer drops the frame with a GST_ELEMENT_ERROR instead of crashing.

Requires the corresponding droidmedia change that adds stride/slice_height to DroidMediaCodecMetaData.

Have in mind the fix has been written by LLM as has been above message. This fixes crash in gst-droid when using qmlglsink.

Corresponding droidmedia PR sailfishos/droidmedia#139

(gdb) bt
#0  gst_droidvec_copy_packed_planes (height=540, width=960, stride_in=1920, in=0x7f7e206d90 "", stride_out=960, out1=0x7f7c5a7c58 "", out0=0x7f7c529358 "") at ../gst/droidcodec/gstdroidvdec.c:126
#1  gst_droidvdec_convert_yuv420_packed_semi_planar_to_i420 (dec=<optimized out>, out=0x7f7eb83648, in=<optimized out>, info=0x7f64000e98, width=<optimized out>, height=<optimized out>) at ../gst/droidcodec/gstdroidvdec.c:271
#2  0x0000007ff0cc0488 in gst_droidvdec_convert_buffer (info=0x7f64000e98, in=0x7f7eb836b8, out=0x7f6400c0e0, dec=0x7fc40a6df0 [GstDroidVDec]) at ../gst/droidcodec/gstdroidvdec.c:457
#3  gst_droidvdec_data_available (data=0x7fc40a6df0, encoded=0x7f7eb836b8) at ../gst/droidcodec/gstdroidvdec.c:608
#4  0x0000007fae1308cc in  ()
#5  0x0000007fc40a6df0 in  ()
#6  0x0000007fc40a48e0 in  ()

gst_droidvec_copy_packed_planes() and the semi-planar I420 conversion
computed the source Y/UV plane pointers from hardcoded alignment
guesses (stride aligned to 128, slice height aligned to 32/16) instead
of the actual buffer layout, and never checked those pointers against
the size of the buffer droidmedia handed over. When a decoder's real
output geometry doesn't match the guess, this reads out of bounds and
segfaults.

Use the stride/slice_height now reported by
droid_media_codec_get_output_info() when available, falling back to
the previous alignment guess otherwise. When the codec doesn't report
real geometry and the aligned guess doesn't fit the buffer droidmedia
actually reports, fall back further to the unpadded exact-dimensions
geometry if that fits instead, since some decoders emit tightly packed
buffers with no slice padding at all. Bounds-check the computed frame
size against DroidMediaData::size before touching the buffer so a bad
guess or undersized buffer drops the frame with a GST_ELEMENT_ERROR
instead of crashing.

Requires the corresponding droidmedia change that adds stride/slice_height
to DroidMediaCodecMetaData.
@Michal-Szczepaniak
Michal-Szczepaniak force-pushed the fix/decoder-stride-slice-height branch from e490867 to f06bd02 Compare August 19, 2026 17:10

@abranson abranson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants