Matthias was right, there is a confusion between samples and frames. I have completed the patch and added a few sanity checks. Reviewers are wellcome.

I will upload a NMU shortly.

BTW, this is not enough to make normalize-audio work under valgrind. Normalize-audio has an additional bug.

Cheers,
Stefan
#! /bin/sh /usr/share/dpatch/dpatch-run
## 22_CVE-2008-5824.dpatch by Stefan Fritsch <s...@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Remove confusion between samples per block and frames perl block, to
## DP: avoid buffer overflow (probably samplesPerBlock should be renamed to
## DP: FramesPerBlock). Add sanity checks inspired by sox source code.

@DPATCH@
diff -urNad audiofile-0.2.6~/libaudiofile/modules/msadpcm.c 
audiofile-0.2.6/libaudiofile/modules/msadpcm.c
--- audiofile-0.2.6~/libaudiofile/modules/msadpcm.c     2009-11-28 
16:07:53.000000000 +0100
+++ audiofile-0.2.6/libaudiofile/modules/msadpcm.c      2009-11-28 
16:07:58.602385909 +0100
@@ -129,8 +129,7 @@
        ms_adpcm_state  *state[2];
 
        /* Calculate the number of bytes needed for decoded data. */
-       outputLength = msadpcm->samplesPerBlock * sizeof (int16_t) *
-               msadpcm->track->f.channelCount;
+       outputLength = msadpcm->samplesPerBlock * sizeof (int16_t);
 
        channelCount = msadpcm->track->f.channelCount;
 
@@ -180,8 +179,8 @@
                The first two samples have already been 'decoded' in
                the block header.
        */
-       samplesRemaining = (msadpcm->samplesPerBlock - 2) *
-               msadpcm->track->f.channelCount;
+       samplesRemaining = msadpcm->samplesPerBlock
+               - 2 * msadpcm->track->f.channelCount;
 
        while (samplesRemaining > 0)
        {
diff -urNad audiofile-0.2.6~/libaudiofile/wave.c 
audiofile-0.2.6/libaudiofile/wave.c
--- audiofile-0.2.6~/libaudiofile/wave.c        2009-11-28 16:07:58.206388930 
+0100
+++ audiofile-0.2.6/libaudiofile/wave.c 2009-11-28 16:13:42.814999480 +0100
@@ -204,6 +204,7 @@
                        AUpvlist        pv;
                        long            l;
                        void            *v;
+                       int             minBlockLength;
 
                        if (track->f.channelCount != 1 &&
                                track->f.channelCount != 2)
@@ -216,11 +217,20 @@
                        af_fread(&bitsPerSample, 1, 2, fp);
                        bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample);
 
+                       if (bitsPerSample != 4)
+                       {
+                               _af_error(AF_BAD_WIDTH,
+                                       "bad sample width of %hd bits",
+                                       bitsPerSample);
+                               return AF_FAIL;
+                       }
+
                        af_fread(&extraByteCount, 1, 2, fp);
                        extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount);
 
                        af_fread(&samplesPerBlock, 1, 2, fp);
-                       samplesPerBlock = 
LENDIAN_TO_HOST_INT16(samplesPerBlock);
+                       samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock)
+                               * channelCount;
 
                        af_fread(&numCoefficients, 1, 2, fp);
                        numCoefficients = 
LENDIAN_TO_HOST_INT16(numCoefficients);
@@ -242,6 +252,18 @@
                                wave->msadpcmCoefficients[i][1] = a1;
                        }
 
+                       minBlockLength = 7 * channelCount; /* header */
+                       if (samplesPerBlock > 2)
+                               minBlockLength += ( ( samplesPerBlock - 2 ) * 
channelCount + 1) / 2;
+
+                       if (blockAlign < minBlockLength)
+                       {
+                               _af_error(AF_BAD_FRAMECNT,
+                                       "blockAlign %hd too small for %hd 
samplesPerBlock",
+                                       blockAlign, samplesPerBlock);
+                               return AF_FAIL;
+                       }
+
                        track->f.sampleWidth = 16;
                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
                        track->f.compressionType = AF_COMPRESSION_MS_ADPCM;
@@ -284,11 +306,36 @@
                        af_fread(&bitsPerSample, 1, 2, fp);
                        bitsPerSample = LENDIAN_TO_HOST_INT16(bitsPerSample);
 
+                       if (bitsPerSample != 4)
+                       {
+                               _af_error(AF_BAD_WIDTH,
+                                       "bad sample width of %hd bits",
+                                       bitsPerSample);
+                               return AF_FAIL;
+                       }
+
                        af_fread(&extraByteCount, 1, 2, fp);
                        extraByteCount = LENDIAN_TO_HOST_INT16(extraByteCount);
 
                        af_fread(&samplesPerBlock, 1, 2, fp);
-                       samplesPerBlock = 
LENDIAN_TO_HOST_INT16(samplesPerBlock);
+                       samplesPerBlock = LENDIAN_TO_HOST_INT16(samplesPerBlock)
+                               * channelCount;
+
+                       /* per channel, ima has blocks of len 4, the 1st has 
1st sample, the others
+                        * up to 8 samples per block,
+                        * so number of later blocks is (nsamp-1 + 7)/8, total 
blocks/chan is
+                        * (nsamp-1+7)/8 + 1 = (nsamp+14)/8
+                        */
+
+                       minBlockLength = ( samplesPerBlock + 14 )/8 * 4 * 
channelCount;
+
+                       if (blockAlign < minBlockLength)
+                       {
+                               _af_error(AF_BAD_FRAMECNT,
+                                       "blockAlign %hd too small for %hd 
samplesPerBlock",
+                                       blockAlign, samplesPerBlock);
+                               return AF_FAIL;
+                       }
 
                        track->f.sampleWidth = 16;
                        track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;

Reply via email to