[FFmpeg-trac] #9314(avcodec:new): Usage-of-uninitialized value

FFmpeg trac at avcodec.org
Fri Jul 2 02:24:08 EEST 2021


#9314: Usage-of-uninitialized value
-------------------------------------+-------------------------------------
             Reporter:  Andrew Bao   |                     Type:  defect
               Status:  new          |                 Priority:  important
            Component:  avcodec      |                  Version:
             Keywords:  Usage-of-    |  unspecified
  uninitialized value bug            |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 Summary of the bug:
 In libavcodec/vorbisec.c, function vorbis_encode_init():
 It partially initializes the structure vorbis_enc_context, leading to the
 memory pointed by venc in an uninitialized state.

 Details:

 In function vorbis_encode_init(), it will initialzie structure
 vorbis_enc_context by calling create_vorbis_context(). However, it
 initalizes all the field except struct FFBufQueue bufqueue.


 {{{
 struct FFBufQueue {
  50     AVFrame *queue[FF_BUFQUEUE_SIZE];
  51     unsigned short head;
  52     unsigned short available; /**< number of available buffers */
  53 };
 }}}



 Then bufqueue will be used in several places:

 move_audio():
 {{{
 1073         cur = ff_bufqueue_get(&venc->bufqueue);
 }}}

 vorbis_encode_frame():


 {{{
 1107         ff_bufqueue_add(avctx, &venc->bufqueue, clone);
 1112         need_more = venc->bufqueue.available * avctx->frame_size <
 frame_size;
 1119         if (venc->bufqueue.available * avctx->frame_size <
 frame_size) {
 1120             int frames_needed = (frame_size/avctx->frame_size) -
 venc->bufqueue.available;
 1128         ff_bufqueue_add(avctx, &venc->bufqueue, empty);



 }}}

 Since venc->bufqueue are not initialized, the fields


 {{{
 unsigned short head;
 unsigned short available;
 }}}


 are undecidable. It might be set to zero or a random value inherited from
 the previous stack.

 In this case, if the variable available and head are set to random values,
 it will cause the program:
 1. array read out of bound, leading to crash

 {{{

    AVFrame *ret = queue->queue[queue->head];
 }}}

 2. arbitrary memory write, leading to crash or code execution

 {{{
 BUCKET(queue->available++) = buf;
 }}}

 3. Change control flow
 if (venc->bufqueue.available * avctx->frame_size < frame_size) {

 4. change variable, running out of memory :

 {{{
 int frames_needed = (frame_size/avctx->frame_size) -
 venc->bufqueue.available;

  for (i = 0; i < frames_needed; i++) {
               AVFrame *empty = spawn_empty_frame(avctx, venc->channels);

 }}}



 recommend fix:
 initialized struct FFBufQueue bufqueue during initialization
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9314>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list