[vlc-commits] [Git][videolan/vlc][master] 10 commits: misc: picture: fix user-after-free on picture date

Steve Lhomme (@robUx4) gitlab at videolan.org
Mon Jan 30 17:43:14 UTC 2023



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
32123a74 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
misc: picture: fix user-after-free on picture date

- - - - -
189b4c4e by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
medialibrary: Thumbnailer: destroy request after it completes

Destroy the thumbnailing request after it completes to free the
associated resources. See also the following commit changing the API:
ca3b131594764f5658094ab7db876fa0274d13c1

- - - - -
1a4a668e by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
test: medialibrary: remove stray code from test

Copied from the image.c tests, but unused in the medialibrary test and
leading to memory leaks of picture.

- - - - -
f22ae10a by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
test: medialibrary: fix leak on vlc_ml_media_t

- - - - -
004b9900 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
misc: thumbnailer: release picture when interrupted

If we were interrupted, we cannot notify the picture anymore so it needs
to be dropped. The behaviour is the same as if using picture_Export
here, and might not be kept in the future, but the goal is to have the
tests working and checking memory leaks before changing the behaviour,
which is also the same as the encoders currently.

- - - - -
cccc085e by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
jpeg: fix picture release on encoder

Encoders are currently supposed to consume the given picture.

- - - - -
d4c93a29 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
png: fix picture release on encoder

Encoders are currently supposed to consume the given picture.

- - - - -
5a145f34 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
avcodec: encoder: fix picture release

Encoders are currently supposed to consume the given picture.

- - - - -
5dde7db3 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
codec: vpx: fix picture release on encoder

Encoders are currently supposed to consume the given picture.

- - - - -
1bf09fe8 by Alexandre Janniaux at 2023-01-30T17:29:38+00:00
image: fix picture leak in case of error

The picture is expected to be consumed, as-if it was given to an
encoder, so we also need to release it in case of error.

- - - - -


10 changed files:

- modules/codec/avcodec/encoder.c
- modules/codec/jpeg.c
- modules/codec/png.c
- modules/codec/vpx.c
- modules/misc/medialibrary/Thumbnailer.cpp
- src/input/thumbnailer.c
- src/misc/image.c
- src/misc/picture.c
- test/modules/misc/medialibrary.c
- test/src/input/thumbnail.c


Changes:

=====================================
modules/codec/avcodec/encoder.c
=====================================
@@ -1280,6 +1280,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
     }
 
     block_t *p_block = encode_avframe( p_enc, p_sys, frame );
+    picture_Release( p_pict );
 
     return p_block;
 }


=====================================
modules/codec/jpeg.c
=====================================
@@ -651,6 +651,7 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
     block_t *p_block = block_Alloc(p_sys->i_blocksize);
     if (p_block == NULL)
     {
+        picture_Release(p_pic);
         return NULL;
     }
 
@@ -735,6 +736,7 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
 
     p_block->i_buffer = size;
     p_block->i_dts = p_block->i_pts = p_pic->date;
+    picture_Release(p_pic);
 
     return p_block;
 
@@ -751,6 +753,7 @@ error:
     free(p_row_pointers);
 
     block_Release(p_block);
+    picture_Release(p_pic);
 
     return NULL;
 }


=====================================
modules/codec/png.c
=====================================
@@ -446,6 +446,7 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
     block_t *p_block = block_Alloc( p_sys->i_blocksize );
     if( p_block == NULL )
     {
+        picture_Release( p_pic );
         return NULL;
     }
 
@@ -453,6 +454,7 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
     if( p_png == NULL )
     {
         block_Release( p_block );
+        picture_Release( p_pic );
         return NULL;
     }
 
@@ -519,6 +521,7 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
     p_block->i_buffer = i_start - p_block->i_buffer;
 
     p_block->i_dts = p_block->i_pts = p_pic->date;
+    picture_Release( p_pic );
 
     return p_block;
 
@@ -527,5 +530,6 @@ static block_t *EncodeBlock(encoder_t *p_enc, picture_t *p_pic)
     png_destroy_write_struct( &p_png, p_info ? &p_info : NULL );
 
     block_Release(p_block);
+    picture_Release( p_pic );
     return NULL;
 }


=====================================
modules/codec/vpx.c
=====================================
@@ -484,6 +484,7 @@ static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
     /* Create and initialize the vpx_image */
     if (!vpx_img_wrap(&img, VPX_IMG_FMT_I420, i_w, i_h, 32, p_pict->p[0].p_pixels)) {
         VPX_ERR(p_enc, ctx, "Failed to wrap image");
+        picture_Release(p_pict);
         return NULL;
     }
 
@@ -500,6 +501,7 @@ static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
     if (res != VPX_CODEC_OK) {
         VPX_ERR(p_enc, ctx, "Failed to encode frame");
         vpx_img_free(&img);
+        picture_Release(p_pict);
         return NULL;
     }
 
@@ -527,6 +529,7 @@ static block_t *Encode(encoder_t *p_enc, picture_t *p_pict)
         }
     }
     vpx_img_free(&img);
+    picture_Release(p_pict);
     return p_out;
 }
 


=====================================
modules/misc/medialibrary/Thumbnailer.cpp
=====================================
@@ -49,7 +49,7 @@ void Thumbnailer::onThumbnailComplete( void* data, picture_t* thumbnail )
     {
         vlc::threads::mutex_locker lock( ctx->thumbnailer->m_mutex );
         ctx->done = true;
-        ctx->thumbnail = thumbnail ? picture_Hold( thumbnail ) : nullptr;
+        ctx->thumbnail = thumbnail;
         ctx->thumbnailer->m_currentContext = nullptr;
     }
     ctx->thumbnailer->m_cond.signal();
@@ -83,6 +83,9 @@ bool Thumbnailer::generate( const medialibrary::IMedia&, const std::string& mrl,
     if ( ctx.thumbnail == nullptr )
         return false;
 
+    vlc_thumbnailer_DestroyRequest(m_thumbnailer.get(), ctx.request);
+    ctx.request = NULL;
+
     /* Both picture_Export and ThumbnailerCtx will release the thumbnail, so
      * ensure that only picture_Export does. */
     picture_t *thumbnail = nullptr;


=====================================
src/input/thumbnailer.c
=====================================
@@ -213,8 +213,7 @@ RunnableRun(void *userdata)
 
     if (notify)
         NotifyThumbnail(task, pic);
-
-    if (pic != NULL)
+    else if (pic != NULL)
         picture_Release(pic);
 
     input_Stop(input);


=====================================
src/misc/image.c
=====================================
@@ -393,7 +393,10 @@ static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic,
     {
         p_image->p_enc = CreateEncoder( p_image->p_parent,
                                         p_fmt_in, p_fmt_out );
-        if( !p_image->p_enc ) return NULL;
+        if( !p_image->p_enc ) {
+            picture_Release( p_pic );
+            return NULL;
+        }
     }
 
     /* Check if we need chroma conversion or resizing */
@@ -427,6 +430,7 @@ static block_t *ImageWrite( image_handler_t *p_image, picture_t *p_pic,
 
             if( !p_image->p_converter )
             {
+                picture_Release( p_pic );
                 return NULL;
             }
         }


=====================================
src/misc/picture.c
=====================================
@@ -609,6 +609,7 @@ int picture_Export( vlc_object_t *p_obj,
     if( !p_image )
         return VLC_ENOMEM;
 
+    vlc_tick_t date = p_picture->date;
     block_t *p_block = image_Write( p_image, p_picture, &fmt_in, &fmt_out );
 
     image_HandlerDelete( p_image );
@@ -617,7 +618,7 @@ int picture_Export( vlc_object_t *p_obj,
         return VLC_EGENERIC;
 
     p_block->i_pts =
-    p_block->i_dts = p_picture->date;
+    p_block->i_dts = date;
 
     if( p_fmt )
         *p_fmt = fmt_out;


=====================================
test/modules/misc/medialibrary.c
=====================================
@@ -66,19 +66,6 @@ static int OpenIntf(vlc_object_t *root)
         return VLC_SUCCESS;
     }
 
-    video_format_t fmt_in;
-    video_format_Init(&fmt_in, VLC_CODEC_RGBA);
-    fmt_in.i_width = fmt_in.i_visible_width = 800;
-    fmt_in.i_height = fmt_in.i_visible_height = 600;
-
-    video_format_t fmt_out;
-    video_format_Init(&fmt_out, VLC_CODEC_PNG);
-    fmt_out.i_width = fmt_out.i_visible_width = 800;
-    fmt_out.i_height = fmt_out.i_visible_height = 600;
-
-    picture_t *picture = picture_NewFromFormat(&fmt_in);
-    assert(picture != NULL);
-
     #define MOCK_URL "mock://video_track_count=1;length=100000000;" \
                      "video_width=800;video_height=600"
     vlc_ml_media_t *media = vlc_ml_new_external_media(ml, MOCK_URL);
@@ -94,6 +81,8 @@ static int OpenIntf(vlc_object_t *root)
     vlc_sem_wait(&sem);
     vlc_ml_event_unregister_callback(ml, listener);
 
+    vlc_ml_media_release(media);
+
     return VLC_SUCCESS;
 }
 


=====================================
test/src/input/thumbnail.c
=====================================
@@ -96,6 +96,7 @@ static void thumbnailer_callback( void* data, picture_t* thumbnail )
         }
         assert( thumbnail->date == expected_date && "Unexpected picture date");
 #endif
+        picture_Release( thumbnail );
     }
     else
         assert( !test_params[p_ctx->test_idx].b_expected_success &&



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/d23d357447ffc4fdadee8fe4a1f82e532186b797...1bf09fe8d6ca2b7d90d48b29f8d0f2164a84d382

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/d23d357447ffc4fdadee8fe4a1f82e532186b797...1bf09fe8d6ca2b7d90d48b29f8d0f2164a84d382
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list