diff options
author | Janne Grunau <janne-vlc@jannau.net> | 2018-11-15 23:40:47 +0300 |
---|---|---|
committer | Janne Grunau <janne-vlc@jannau.net> | 2018-11-16 00:29:05 +0300 |
commit | e890a66f773d12d0680a6fe50807800921dac504 (patch) | |
tree | a7c172b2296808f5442527e3f4ca96753f5791e1 | |
parent | 597a6eb9cee41ddbebf019f3b20f50e8da48061c (diff) |
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.
-rw-r--r-- | src/lib.c | 16 |
1 files changed, 16 insertions, 0 deletions
@@ -259,6 +259,22 @@ void dav1d_close(Dav1dContext **const c_out) { 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); |