mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 17:51:16 +00:00
d3d11decoder: Fix potential use after free
A DPB buffer held by codec picture object may not be writable at the moment, then gst_buffer_make_writable() will unref passed buffer. Specifically, the use after free or double free can happen if: * Crop meta of buffer copy is required because of non-zero top-left crop position * zero-copy is possible with crop meta * A picture was duplicated, interlaced h264 stream for example Interlaced h264 stream with non-zero top-left crop position is not very common but it's possible configuration in theory. Thus gst_buffer_make_writable() should be called with GstVideoCodecFrame.output_buffer directly. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6706>
This commit is contained in:
parent
6d228c420c
commit
b9e51facdd
1 changed files with 15 additions and 15 deletions
|
@ -1551,6 +1551,7 @@ gst_d3d11_decoder_output_picture (GstD3D11Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
|
bool attach_crop_meta = false;
|
||||||
|
|
||||||
if (picture->discont_state) {
|
if (picture->discont_state) {
|
||||||
g_clear_pointer (&decoder->input_state, gst_video_codec_state_unref);
|
g_clear_pointer (&decoder->input_state, gst_video_codec_state_unref);
|
||||||
|
@ -1593,21 +1594,8 @@ gst_d3d11_decoder_output_picture (GstD3D11Decoder * decoder,
|
||||||
mem = gst_buffer_peek_memory (view_buffer, 0);
|
mem = gst_buffer_peek_memory (view_buffer, 0);
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||||
|
|
||||||
if (decoder->need_crop) {
|
if (decoder->need_crop)
|
||||||
GstVideoCropMeta *crop_meta;
|
attach_crop_meta = true;
|
||||||
|
|
||||||
view_buffer = gst_buffer_make_writable (view_buffer);
|
|
||||||
crop_meta = gst_buffer_get_video_crop_meta (view_buffer);
|
|
||||||
if (!crop_meta)
|
|
||||||
crop_meta = gst_buffer_add_video_crop_meta (view_buffer);
|
|
||||||
|
|
||||||
crop_meta->x = decoder->offset_x;
|
|
||||||
crop_meta->y = decoder->offset_y;
|
|
||||||
crop_meta->width = decoder->info.width;
|
|
||||||
crop_meta->height = decoder->info.height;
|
|
||||||
|
|
||||||
GST_TRACE_OBJECT (decoder, "Attatching crop meta");
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->output_buffer = gst_buffer_ref (view_buffer);
|
frame->output_buffer = gst_buffer_ref (view_buffer);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1628,6 +1616,18 @@ gst_d3d11_decoder_output_picture (GstD3D11Decoder * decoder,
|
||||||
GST_BUFFER_FLAG_SET (frame->output_buffer, buffer_flags);
|
GST_BUFFER_FLAG_SET (frame->output_buffer, buffer_flags);
|
||||||
gst_codec_picture_unref (picture);
|
gst_codec_picture_unref (picture);
|
||||||
|
|
||||||
|
if (attach_crop_meta) {
|
||||||
|
frame->output_buffer = gst_buffer_make_writable (frame->output_buffer);
|
||||||
|
|
||||||
|
auto crop_meta = gst_buffer_add_video_crop_meta (frame->output_buffer);
|
||||||
|
crop_meta->x = decoder->offset_x;
|
||||||
|
crop_meta->y = decoder->offset_y;
|
||||||
|
crop_meta->width = decoder->info.width;
|
||||||
|
crop_meta->height = decoder->info.height;
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT (decoder, "Attatching crop meta");
|
||||||
|
}
|
||||||
|
|
||||||
return gst_video_decoder_finish_frame (videodec, frame);
|
return gst_video_decoder_finish_frame (videodec, frame);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
Loading…
Reference in a new issue