]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/cbs: Fix potential double-free when adding unit fails
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Mon, 18 Nov 2019 07:47:58 +0000 (08:47 +0100)
committerMark Thompson <sw@jkqxz.net>
Sun, 9 Feb 2020 22:23:29 +0000 (22:23 +0000)
ff_cbs_insert_unit_data() has two modes of operation: It can insert a
unit with a newly created reference to an already existing AVBuffer; or
it can take a buffer and create an AVBuffer for it. Said buffer will
then become owned by the unit lateron.

A potential memleak/double-free exists in the second case, because if
creating the AVBuffer fails, the function immediately returns, but when
it fails lateron, the supplied buffer will be freed. The caller has no
way to distinguish between these two outcomes. The only such caller
(cbs_jpeg_split_fragment() in cbs_jpeg.c) opted for a potential
double-free.

This commit changes this by explicitly stating that a non-refcounted
buffer will be freed on error. The aforementioned caller has been
brought in line with this.

Fixes CID 1452623.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
libavcodec/cbs.c
libavcodec/cbs.h
libavcodec/cbs_jpeg.c

index 0badb192d9fa49dfa51786b67156ed5faacac3ac..0bd5e1ac5db67d16c64eab22d6e35a16c374fec4 100644 (file)
@@ -775,8 +775,11 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
         data_ref = av_buffer_ref(data_buf);
     else
         data_ref = av_buffer_create(data, data_size, NULL, NULL, 0);
-    if (!data_ref)
+    if (!data_ref) {
+        if (!data_buf)
+            av_free(data);
         return AVERROR(ENOMEM);
+    }
 
     err = cbs_insert_unit(ctx, frag, position);
     if (err < 0) {
index cdb777d111510727639774ff3364e30dbaf2cad1..9ca1fbd60902c6ab746c6c0352a79b8a4e722f6a 100644 (file)
@@ -376,7 +376,8 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx,
  * Insert a new unit into a fragment with the given data bitstream.
  *
  * If data_buf is not supplied then data must have been allocated with
- * av_malloc() and will become owned by the unit after this call.
+ * av_malloc() and will on success become owned by the unit after this
+ * call or freed on error.
  */
 int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx,
                             CodedBitstreamFragment *frag,
index b189cbd9b7680397b80492541647f21b8817d216..b52e5c5823f8f32a0c3827cece35f29645b47724 100644 (file)
@@ -225,11 +225,8 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
 
         err = ff_cbs_insert_unit_data(ctx, frag, unit, marker,
                                       data, data_size, data_ref);
-        if (err < 0) {
-            if (!data_ref)
-                av_freep(&data);
+        if (err < 0)
             return err;
-        }
 
         if (next_marker == -1)
             break;