Fixed bug 1091 - Hardcoded size in SDL_audiocvt.c may lead to heap/stack corruption
authorSam Lantinga
Sun, 08 Jan 2012 17:20:33 -0500
changeset 61959ee905f656b2
parent 6194 ba275696ab7a
child 6196 f1a312da2669
Fixed bug 1091 - Hardcoded size in SDL_audiocvt.c may lead to heap/stack corruption

Markovtsev Vadim 2011-01-18 22:00:16 PST

SDL_audiocvt.c:

static void SDLCALL
SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format):

#define dup_chans_1_to_2(type) \
{ \
const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
for (i = cvt->len_cvt / 2; i; --i, --src) { \
const type val = *src; \
dst -= 2; \
dst[0] = dst[1] = val; \
} \
}

Pay attention to cvt->len_cvt / 2. 2 is the sizeof(Uint16), hovewer, below we
see that the conversion function supports Uint8 and Uint32:

switch (SDL_AUDIO_BITSIZE(format)) {
case 8:
dup_chans_1_to_2(Uint8);
break;
case 16:
dup_chans_1_to_2(Uint16);
break;
case 32:
dup_chans_1_to_2(Uint32);
break;
}

If type is Uint32, src will be decreased twice as it should be, memory being
written before the cvt->buf. If type is Uint8, the conversion will not be
complete. I suggest to change that define to

#define dup_chans_1_to_2(type) \
{ \
const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
for (i = cvt->len_cvt / sizeof(type); i; --i, --src) { \
const type val = *src; \
dst -= 2; \
dst[0] = dst[1] = val; \
} \
}

I tested that and now it's working fine. I did not consider the similar defines
in functions nearby.
src/audio/SDL_audiocvt.c
     1.1 --- a/src/audio/SDL_audiocvt.c	Sun Jan 08 17:10:57 2012 -0500
     1.2 +++ b/src/audio/SDL_audiocvt.c	Sun Jan 08 17:20:33 2012 -0500
     1.3 @@ -295,7 +295,7 @@
     1.4      { \
     1.5          const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
     1.6          type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
     1.7 -        for (i = cvt->len_cvt / 2; i; --i, --src) { \
     1.8 +        for (i = cvt->len_cvt / sizeof(type); i; --i, --src) { \
     1.9              const type val = *src; \
    1.10              dst -= 2; \
    1.11              dst[0] = dst[1] = val; \