shithub: dav1d

Download patch

ref: e890a66f773d12d0680a6fe50807800921dac504
parent: 597a6eb9cee41ddbebf019f3b20f50e8da48061c
author: Janne Grunau <janne-vlc@jannau.net>
date: Thu Nov 15 16:40:47 EST 2018

frame mt: fix memleak caused by race between dav1d_close and dav1d_decode_frame

The race is exposed by not draining the decoder correctly after
026069693ef (decoupled decoding api). Fixes a memleak with
clusterfuzz-testcase-minimized-dav1d_fuzzer_mt-5728508249112576. Credits
to oss-fuzz.

--- a/src/lib.c
+++ b/src/lib.c
@@ -259,6 +259,22 @@
             pthread_cond_signal(&f->frame_thread.td.cond);
             pthread_mutex_unlock(&f->frame_thread.td.lock);
             pthread_join(f->frame_thread.td.thread, NULL);
+            // free references from dav1d_submit_frame() usually freed by
+            // dav1d_decode_frame
+            for (int i = 0; i < 7; i++) {
+                if (f->refp[i].p.data[0])
+                    dav1d_thread_picture_unref(&f->refp[i]);
+                dav1d_ref_dec(&f->ref_mvs_ref[i]);
+            }
+            dav1d_thread_picture_unref(&f->cur);
+            dav1d_cdf_thread_unref(&f->in_cdf);
+            if (f->frame_hdr.refresh_context)
+                dav1d_cdf_thread_unref(&f->out_cdf);
+            dav1d_ref_dec(&f->cur_segmap_ref);
+            dav1d_ref_dec(&f->prev_segmap_ref);
+            dav1d_ref_dec(&f->mvs_ref);
+            for (int i = 0; i < f->n_tile_data; i++)
+                dav1d_data_unref(&f->tile[i].data);
             freep(&f->frame_thread.b);
             dav1d_freep_aligned(&f->frame_thread.pal_idx);
             dav1d_freep_aligned(&f->frame_thread.cf);