Opened 3 hours ago

#11345 new defect

yuv2rgb functions, use of uninitialised value

Reported by: names_are_hard Owned by:
Priority: normal Component: swscale
Version: unspecified Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Some yuv2rgb* functions, including at least yuv2gbrp_full_X_c(), yuv2rgb_X_c_template() and yuv2rgb_write_full(), have behaviour dependent on uninitialised values due to use in a conditional.

I have guessed the component to be swscale based on file names in valgrind trace, my confidence is moderate.

Samples are attached.

Repro instructions:
valgrind --track-origins=yes ffmpeg_g -i some_sample -nostdin -f null -

Tested against master @ 1e76bd2f39.

Truncated valgrind trace:

==883880== Conditional jump or move depends on uninitialised value(s)
==883880==    at 0x11D68CB: yuv2rgb_write_full (output.c:1932)
==883880==    by 0x11D68CB: yuv2rgb_full_X_c_template (output.c:2123)
==883880==    by 0x11D68CB: yuv2bgr24_full_X_c (output.c:2249)
[...]
==883880==  Uninitialised value was created by a heap allocation
==883880==    at 0x4848DA0: memalign (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==883880==    by 0x4848F01: posix_memalign (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==883880==    by 0x123B6DE: av_malloc (mem.c:107)
==883880==    by 0x1236115: av_image_alloc (imgutils.c:248)
==883880==    by 0x11B4A3C: pass_alloc_output (graph.c:41)
==883880==    by 0x11B4A3C: pass_add (graph.c:64)

This trace shows all three functions being used. Other samples only hit one; I have not tried to find why, I would guess because execution bails out earlier in those cases.

The specific fix should probably find why initialisation is skipped and fix the root cause. This is hard for me to determine, as I have little experience with ffmpeg. Quite possibly, more yuv2rgb* functions can be reached in a similar way, with a different input, given the similarity in traces for the examples provided here.

A more general fix that I would recommend also employing is to use calloc() where possible when allocating structs / object-like entities. On "large" OSes, this is likely to have no performance impact, as the OS will keep a pool of zero pages available for this purpose. If there are concerns about perf on smaller OSes, a malloc-like function could be chosen at build time for these targets.

This would reduce control available to attackers, and make coverage guided fuzzing more efficient. Currently, ffmpeg coverage is non-deterministic on many inputs due to this and similar bugs.

Attachments (1)

yuv2rgb_samples.zip (3.0 KB ) - added by names_are_hard 3 hours ago.

Download all attachments as: .zip

Change History (1)

by names_are_hard, 3 hours ago

Attachment: yuv2rgb_samples.zip added
Note: See TracTickets for help on using tickets.