Ticket #2 (closed defect: fixed)

Opened 7 years ago

Last modified 6 years ago

sndfile demo segfaults due to badly negative RemixChunk length

Reported by: shans Assigned to: somebody
Priority: normal Milestone:
Component: libremix Version:
Severity: normal Keywords:
Cc:

Description

When running the sndfile demo, I get a segmentation fault. Running with DEBUG enabled gives: ...

        SEEK 0x80b3990 @ 0
         [remix_stream_chunkfuncify] thinking of channel 0
         [remix_stream_chunkfuncify] thinking of channel 1
         [remix_stream_chunkfuncify] (0x8176d78, +395) @ 629
         [remix_channel_chunkfuncify] (0x8176e20, +395) @ 629
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_sndfile_read_into_chunk] read 78 bytes
         [remix_channel_chunkfuncify] (0x8176df8, +395) @ 629
         [remix_sndfile_read_into_chunk] read -1119289344 bytes
         [remix_channel_chunkfuncify] channel incomplete, funced -1119289344
         SEEK 0x8176d78 @ -1119288715
Segmentation fault

Change History

08/03/05 12:40:39 changed by shans

Valgrind reckons that the entire Chunk is invalid - remix_chunk_item_valid_length does this:

static RemixCount
remix_chunk_item_valid_length (CDList * l)
{
  CDList * ln = l->next;
  RemixChunk * u = (RemixChunk *)l->data.s_pointer, * un;

  if (ln == RemixNone) {
    return u->length;
  } else {
    un = (RemixChunk *)ln->data.s_pointer;
    return MIN (u->length, un->start_index - u->start_index);
  }
}

This line is the one that valgrind thinks is an invalid read:

    un = (RemixChunk *)ln->data.s_pointer;

Which is the first time that ln's contents are accessed. Hence, I think what's happening is that somewhere else, an invalid element is being linked onto the passed in CDList somehow. This then gives a majorly bung size value when accessed, coz it's not initialised to anything.

08/09/05 18:20:17 changed by shans

A hardware watch at the relevant memory location shows that it's being modified from the correct length (1024) to an incorrect one (negative a lot) during a copy loop in remix_sndfile_read_into_chunk. Particularly, here:

  for (i = 0; i < n; i++) {
    *d++ = *p;
    p += si->info.channels;
  }

However _this_ seems to be because the parameter 'offset' is bung.

  d = &chunk->data[offset];

and offset is 0xbd490000. Wierd.

08/09/05 18:35:58 changed by shans

OK, I think I've tracked it down. remix_sndfile_read_into_chunk is called with an offset of 0x3fb, and the function attempts to write 78 bytes into the chunk that's passed in, starting at 0x3fb. However, there's only 0x400 samples total in a chunk, so random memory is written into. This memory happens to be the length record of the next chunk, which causes the above behaviour.

static RemixCount
remix_sndfile_read_into_chunk (RemixEnv * env, RemixChunk * chunk,
			       RemixCount offset, RemixCount count,
			       int channelname, void * data)

    *******************
    * offset is 0x3FB * 
    *******************


{
  RemixBase * sndfile = (RemixBase *)data;
  RemixPCM * d, * p;
  RemixCount remaining = count, written = 0, n, i;
  RemixSndfileInstance * si = (RemixSndfileInstance *)sndfile->instance_data;

  d = &chunk->data[offset];

  n = MIN (remaining, BLOCK_FRAMES);
  if (channelname == 0)
    remix_sndfile_read_update (env, sndfile, n);

  n = si->pcm_n;

  ****************************************************************
  * n is 78.  Should this actually be MIN(si->pcm_n, remaining)? *
  * 0x3fb + 78 is LARGER than 0x400, the size of the chunk!      *
  ****************************************************************

  p = si->pcm;
  p += channelname;
  
  for (i = 0; i < n; i++) {    ****************************************
    *d++ = *p;                 * BAM, this loop does some overwriting *
    p += si->info.channels;    ****************************************
  }
  ...

08/10/05 21:01:46 changed by shans

  • status changed from new to closed.
  • resolution set to fixed.

Fixed! It was as I suspected.