summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2021-04-21 19:25:22 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2023-09-30 23:05:42 +0200
commit0cfc7418bbf55f7b316862598c4e59434c65b3a8 (patch)
tree4715c121f9f3c8b4cc5bb76c049727f53e25fe26
parent5ba06ad0b87740080a7bc7ddf58c5a65c24c9262 (diff)
avcodec/ffv1dec: Fix data races emanating from copying whole context
When using frame threading, the FFV1 decoder's update_thread_context() function copies the whole context and afterwards restores some allocated fields with backups made earlier. Among these fields are the ThreadFrames and the source context's ThreadFrames can change concurrently without any synchronization, leading to data races which are undefined behaviour even if they don't lead to problems in practice (as the destination's own ThreadFrames are restored directly thereafter). Fix this by only copying the actually needed fields. Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
-rw-r--r--libavcodec/ffv1dec.c19
1 files changed, 6 insertions, 13 deletions
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index cdf72a25dd..95beae09ad 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -1072,18 +1072,12 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
if (dst == src)
return 0;
- {
- ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture;
- uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
- struct FFV1Context *slice_context[MAX_SLICES];
- memcpy(initial_states, fdst->initial_states, sizeof(fdst->initial_states));
- memcpy(slice_context, fdst->slice_context , sizeof(fdst->slice_context));
-
- memcpy(fdst, fsrc, sizeof(*fdst));
- memcpy(fdst->initial_states, initial_states, sizeof(fdst->initial_states));
- memcpy(fdst->slice_context, slice_context , sizeof(fdst->slice_context));
- fdst->picture = picture;
- fdst->last_picture = last_picture;
+ copy_fields(fdst, fsrc, fsrc);
+ fdst->use32bit = fsrc->use32bit;
+ memcpy(fdst->state_transition, fsrc->state_transition,
+ sizeof(fdst->state_transition));
+ memcpy(fdst->quant_table, fsrc->quant_table, sizeof(fsrc->quant_table));
+
for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) {
FFV1Context *fssrc = fsrc->slice_context[i];
FFV1Context *fsdst = fdst->slice_context[i];
@@ -1091,7 +1085,6 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
}
av_assert0(!fdst->plane[0].state);
av_assert0(!fdst->sample_buffer);
- }
av_assert1(fdst->max_slice_count == fsrc->max_slice_count);