Coordinated Disclosure Timeline

Project

Gstreamer

Tested Version

Details

Issue 1: Stack-buffer overflow in vorbis_handle_identification_packet (GHSL-2024-115)

A stack-buffer overflow has been detected in the vorbis_handle_identification_packet function within gstvorbisdec.c.

The position array is a stack-allocated buffer of size 64. If vd->vi.channels exceeds 64, the for loop will write beyond the boundaries of the position array:

static GstFlowReturn vorbis_handle_identification_packet (GstVorbisDec * vd){

GstAudioInfo info;

  switch (vd->vi.channels) {
   ...
    default:{
      GstAudioChannelPosition position[64];
      gint i, max_pos = MAX (vd->vi.channels, 64);
   ...

    for (i = 0; i < max_pos; i++)
        position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
      gst_audio_info_set_format (&info, GST_VORBIS_AUDIO_FORMAT, vd->vi.rate, vd->vi.channels, position);
      break;
    }
  }
  gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (vd), &info);

  vd->info = info;
  ...
  return GST_FLOW_OK;
}

The value written will always be GST_AUDIO_CHANNEL_POSITION_NONE.

This vulnerability allows to overwrite the EIP address allocated in the stack. Additionally, this bug can overwrite the GstAudioInfo info structure.

Impact

This vulnerability may corrupt control data on the stack, such as the return address (EIP) or the GstAudioInfo info structure.

Issue 2: Stack-buffer overflow in gst_opus_dec_parse_header (GHSL-2024-116)

A stack-buffer overflow has been detected in the gst_opus_dec_parse_header function within `gstopusdec.c’.

The pos array is a stack-allocated buffer of size 64. If n_channels exceeds 64, the for loop will write beyond the boundaries of the pos array:

static GstFlowReturn gst_opus_dec_parse_header (GstOpusDec * dec, GstBuffer * buf){

  GstAudioChannelPosition pos[64];
  const GstAudioChannelPosition *posn = NULL;
  guint8 n_channels;
  ...
  dec->n_channels = n_channels;
  ...
    switch (dec->n_channels) {
  ...
      default:{
        gint i;
  ...
        for (i = 0; i < dec->n_channels; i++)
          pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;

        posn = pos;
      }
  ...
}

The value written will always be GST_AUDIO_CHANNEL_POSITION_NONE.

This bug allows to overwrite the EIP address allocated in the stack.

Impact

This vulnerability may corrupt control data on the stack, such as the return address (EIP).

Issue 3: OOB-Write in gst_parse_vorbis_setup_packet (GHSL-2024-117)

An OOB-Write has been detected in the function gst_parse_vorbis_setup_packet within vorbis_parse.c.

The integer size is read from the input file without proper validation. As a result, size can exceed the fixed size of the pad->vorbis_mode_sizes array (which size is 256):

struct _GstVorbisEnc {
  ....
  int              vorbis_mode_sizes[256];
};

When this happens, the for loop overwrites the entire pad structure with 0s and 1s, affecting adjacent memory as well.

void gst_parse_vorbis_setup_packet (GstOggStream * pad, ogg_packet * op){

  unsigned char *current_pos = &op->packet[op->bytes - 1];
  int offset;
  int size;
  int size_check;
  int *mode_size_ptr;
  int i;
  int ii;

  ...

  mode_size_ptr = pad->vorbis_mode_sizes;

  for (i = 0; i < size; i++) {
    offset = (offset + 1) % 8;
    if (offset == 0)
      current_pos += 1;
    *mode_size_ptr++ = (current_pos[0] >> offset) & 0x1;
    current_pos += 5;
  }

}

Impact

This OOB-write can overwrite up to 380 bytes of memory beyond the boundaries of the pad->vorbis_mode_sizes array.

This vulnerability triggers other memory issues (such as invalid frees) and disrupts the program’s execution flow.

Issue 4: Null pointer dereference in gst_gdk_pixbuf_dec_flush (GHSL-2024-118)

A null pointer dereference vulnerability has been identified in gst_gdk_pixbuf_dec_flush within gstgdkpixbufdec.c.

This function invokes memcpy, using out_pix as the destination address. out_pix is expected to point to the frame 0 from the frame structure, which is read from the input file.

However, in certain situations, it can points to a NULL frame, causing the subsequent call to memcpy to attempt writing to the null address (0x00), leading to a null pointer dereference.

static GstFlowReturn gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter) {
  ...
  guint8 *out_pix;
  ...
  GstVideoFrame frame;
  ...
  gst_video_frame_map (&frame, &filter->info, outbuf, GST_MAP_WRITE);
  out_pix = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
  out_rowstride = GST_VIDEO_FRAME_PLANE_STRIDE (&frame, 0);

  for (y = 0; y < height; y++) {
    memcpy (out_pix, in_pix, width * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, 0));
    in_pix += in_rowstride;
    out_pix += out_rowstride;
  }
  ...

Impact

This vulnerability can result in a Denial of Service (DoS) by triggering a segmentation fault (SEGV).

CVE

Credit

These issues were discovered and reported by GHSL team member @antonio-morales (Antonio Morales).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2024-115, GHSL-2024-116, GHSL-2024-117, or GHSL-2024-118 in any communication regarding these issues.