diff options
author | Chengfeng Ye <cyeaa@connect.ust.hk> | 2021-08-26 07:40:46 -0700 |
---|---|---|
committer | Thilo Borgmann <thilo.borgmann@mail.de> | 2021-09-17 15:31:40 +0200 |
commit | 54d201ae20d37e1ff5b2fba502fb82e23f090ddb (patch) | |
tree | 9e285b15a6f2b30489a1a8447ca57b52438e6ff4 /libavdevice | |
parent | 9bbdfbfb32e5ad94a06a4ce2830a655009378684 (diff) |
libavdevice/avfoundation.m: fix potential unreleased lock issue
The problem here is that the lock ctx->frame_lock will become
an unreleased lock if the program returns at patched lines.
Bug tracker link: https://trac.ffmpeg.org/ticket/9386\#ticket
Signed-off-by: Chengfeng Ye <cyeaa@connect.ust.hk>
Diffstat (limited to 'libavdevice')
-rw-r--r-- | libavdevice/avfoundation.m | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/libavdevice/avfoundation.m b/libavdevice/avfoundation.m index 8ce3d064c5..0cd6e646d5 100644 --- a/libavdevice/avfoundation.m +++ b/libavdevice/avfoundation.m @@ -1067,10 +1067,12 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) } else if (block_buffer != nil) { length = (int)CMBlockBufferGetDataLength(block_buffer); } else { + unlock_frames(ctx); return AVERROR(EINVAL); } if (av_new_packet(pkt, length) < 0) { + unlock_frames(ctx); return AVERROR(EIO); } @@ -1097,21 +1099,26 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) CFRelease(ctx->current_frame); ctx->current_frame = nil; - if (status < 0) + if (status < 0) { + unlock_frames(ctx); return status; + } } else if (ctx->current_audio_frame != nil) { CMBlockBufferRef block_buffer = CMSampleBufferGetDataBuffer(ctx->current_audio_frame); int block_buffer_size = CMBlockBufferGetDataLength(block_buffer); if (!block_buffer || !block_buffer_size) { + unlock_frames(ctx); return AVERROR(EIO); } if (ctx->audio_non_interleaved && block_buffer_size > ctx->audio_buffer_size) { + unlock_frames(ctx); return AVERROR_BUFFER_TOO_SMALL; } if (av_new_packet(pkt, block_buffer_size) < 0) { + unlock_frames(ctx); return AVERROR(EIO); } @@ -1131,6 +1138,7 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, ctx->audio_buffer); if (ret != kCMBlockBufferNoErr) { + unlock_frames(ctx); return AVERROR(EIO); } @@ -1142,7 +1150,11 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) int##bps##_t **src; \ int##bps##_t *dest; \ src = av_malloc(ctx->audio_channels * sizeof(int##bps##_t*)); \ - if (!src) return AVERROR(EIO); \ + if (!src) { \ + unlock_frames(ctx); \ + return AVERROR(EIO); \ + } \ + \ for (c = 0; c < ctx->audio_channels; c++) { \ src[c] = ((int##bps##_t*)ctx->audio_buffer) + c * num_samples; \ } \ @@ -1162,6 +1174,7 @@ static int avf_read_packet(AVFormatContext *s, AVPacket *pkt) } else { OSStatus ret = CMBlockBufferCopyDataBytes(block_buffer, 0, pkt->size, pkt->data); if (ret != kCMBlockBufferNoErr) { + unlock_frames(ctx); return AVERROR(EIO); } } |