diff mbox series

[FFmpeg-devel,2/2] libavdevice/avfoundation.m: fix potential unreleased lock issue

Message ID 20210826144046.95851-1-cyeaa@connect.ust.hk
State Accepted
Commit 54d201ae20d37e1ff5b2fba502fb82e23f090ddb
Headers show
Series [FFmpeg-devel,1/2] libavdevice/avfoundation.m: fix protential unreleased lock issue | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

YE Chengfeng Aug. 26, 2021, 2:40 p.m. UTC
The problem here is that the lock ctx->frame_lock will become
an unreleased lock if the program returns at patched lines.

Depends-on: series-0001
Cc: cyeaa@connect.ust.hk
Bug tracker link: https://trac.ffmpeg.org/ticket/9386\#ticket

Signed-off-by: Chengfeng Ye <cyeaa@connect.ust.hk>
---
 libavdevice/avfoundation.m | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Comments

Thilo Borgmann Sept. 17, 2021, 1:32 p.m. UTC | #1
Am 26.08.21 um 16:40 schrieb Chengfeng Ye:
> The problem here is that the lock ctx->frame_lock will become
> an unreleased lock if the program returns at patched lines.
> 
> Depends-on: series-0001
> Cc: cyeaa@connect.ust.hk
> Bug tracker link: https://trac.ffmpeg.org/ticket/9386\#ticket
> 
> Signed-off-by: Chengfeng Ye <cyeaa@connect.ust.hk>
> ---
>  libavdevice/avfoundation.m | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)

Pushed, thanks!

-Thilo
diff mbox series

Patch

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);
                 }
             }