[FFmpeg-trac] #11345(swscale:new): yuv2rgb functions, use of uninitialised value

FFmpeg trac at avcodec.org
Thu Dec 12 19:53:41 EET 2024


#11345: yuv2rgb functions, use of uninitialised value
-------------------------------------+-------------------------------------
             Reporter:               |                     Type:  defect
  names_are_hard                     |
               Status:  new          |                 Priority:  normal
            Component:  swscale      |                  Version:
                                     |  unspecified
             Keywords:               |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 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.
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/11345>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list