Commit cdec0ceb authored by Rasmus Thomsen's avatar Rasmus Thomsen Committed by Leonardo Arena

main/sdl: fix multiple vulnerabilities

This fixes CVE-2019-7572, CVE-2019-7573, CVE-2019-7574, CVE-2019-7575, CVE-2019-7576,
CVE-2019-7577, CVE-2019-7578, CVE-2019-7635, CVE-2019-7636, CVE-2019-7637, CVE-2019-7638

closes #10347
parent 8b2c14f6
From 6086741bda4d43cc227500bc7645a829380e6326 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 15 Feb 2019 09:21:45 +0100
Subject: [PATCH] CVE-2019-7572: Fix a buffer overwrite in IMA_ADPCM_decode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If data chunk was longer than expected based on a WAV format
definition, IMA_ADPCM_decode() tried to write past the output
buffer. This patch fixes it.
Based on patch from
<https://bugzilla.libsdl.org/show_bug.cgi?id=4496>.
CVE-2019-7572
https://bugzilla.libsdl.org/show_bug.cgi?id=4495
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 69d62dc..91e89e8 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -336,7 +336,7 @@ static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded,
static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct IMA_ADPCM_decodestate *state;
- Uint8 *freeable, *encoded, *encoded_end, *decoded;
+ Uint8 *freeable, *encoded, *encoded_end, *decoded, *decoded_end;
Sint32 encoded_len, samplesleft;
unsigned int c, channels;
@@ -363,6 +363,7 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
return(-1);
}
decoded = *audio_buf;
+ decoded_end = decoded + *audio_len;
/* Get ready... Go! */
while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) {
@@ -382,6 +383,7 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
}
/* Store the initial sample we start with */
+ if (decoded + 2 > decoded_end) goto invalid_size;
decoded[0] = (Uint8)(state[c].sample&0xFF);
decoded[1] = (Uint8)(state[c].sample>>8);
decoded += 2;
@@ -392,6 +394,8 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
while ( samplesleft > 0 ) {
for ( c=0; c<channels; ++c ) {
if (encoded + 4 > encoded_end) goto invalid_size;
+ if (decoded + 4 * 4 * channels > decoded_end)
+ goto invalid_size;
Fill_IMA_ADPCM_block(decoded, encoded,
c, channels, &state[c]);
encoded += 4;
--
2.20.1
From 3e2c89e516701f3586dfeadec13932f665371d2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 15 Feb 2019 10:36:13 +0100
Subject: [PATCH] CVE-2019-7573, CVE-2019-7576: Fix buffer overreads in
InitMS_ADPCM
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If MS ADPCM format chunk was too short, InitMS_ADPCM() parsing it
could read past the end of chunk data. This patch fixes it.
CVE-2019-7573
https://bugzilla.libsdl.org/show_bug.cgi?id=4491
CVE-2019-7576
https://bugzilla.libsdl.org/show_bug.cgi?id=4490
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 91e89e8..1d446ed 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -44,12 +44,13 @@ static struct MS_ADPCM_decoder {
struct MS_ADPCM_decodestate state[2];
} MS_ADPCM_state;
-static int InitMS_ADPCM(WaveFMT *format)
+static int InitMS_ADPCM(WaveFMT *format, int length)
{
- Uint8 *rogue_feel;
+ Uint8 *rogue_feel, *rogue_feel_end;
int i;
/* Set the rogue pointer to the MS_ADPCM specific data */
+ if (length < sizeof(*format)) goto too_short;
MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
@@ -58,9 +59,11 @@ static int InitMS_ADPCM(WaveFMT *format)
MS_ADPCM_state.wavefmt.bitspersample =
SDL_SwapLE16(format->bitspersample);
rogue_feel = (Uint8 *)format+sizeof(*format);
+ rogue_feel_end = (Uint8 *)format + length;
if ( sizeof(*format) == 16 ) {
rogue_feel += sizeof(Uint16);
}
+ if (rogue_feel + 4 > rogue_feel_end) goto too_short;
MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);
@@ -70,12 +73,16 @@ static int InitMS_ADPCM(WaveFMT *format)
return(-1);
}
for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) {
+ if (rogue_feel + 4 > rogue_feel_end) goto too_short;
MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
}
return(0);
+too_short:
+ SDL_SetError("Unexpected length of a chunk with a MS ADPCM format");
+ return(-1);
}
static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
@@ -485,7 +492,7 @@ SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,
break;
case MS_ADPCM_CODE:
/* Try to understand this */
- if ( InitMS_ADPCM(format) < 0 ) {
+ if ( InitMS_ADPCM(format, lenread) < 0 ) {
was_error = 1;
goto done;
}
--
2.20.1
From 9b2eee24768889378032077423cb6a3221a8ad18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 14 Feb 2019 15:41:47 +0100
Subject: [PATCH] CVE-2019-7574: Fix a buffer overread in IMA_ADPCM_decode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If data chunk was shorter than expected based on a WAV format
definition, IMA_ADPCM_decode() tried to read past the data chunk
buffer. This patch fixes it.
CVE-2019-7574
https://bugzilla.libsdl.org/show_bug.cgi?id=4496
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index b6c49de..2968b3d 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -334,7 +334,7 @@ static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded,
static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct IMA_ADPCM_decodestate *state;
- Uint8 *freeable, *encoded, *decoded;
+ Uint8 *freeable, *encoded, *encoded_end, *decoded;
Sint32 encoded_len, samplesleft;
unsigned int c, channels;
@@ -350,6 +350,7 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
/* Allocate the proper sized output buffer */
encoded_len = *audio_len;
encoded = *audio_buf;
+ encoded_end = encoded + encoded_len;
freeable = *audio_buf;
*audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) *
IMA_ADPCM_state.wSamplesPerBlock*
@@ -365,6 +366,7 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) {
/* Grab the initial information for this block */
for ( c=0; c<channels; ++c ) {
+ if (encoded + 4 > encoded_end) goto invalid_size;
/* Fill the state information for this block */
state[c].sample = ((encoded[1]<<8)|encoded[0]);
encoded += 2;
@@ -387,6 +389,7 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels;
while ( samplesleft > 0 ) {
for ( c=0; c<channels; ++c ) {
+ if (encoded + 4 > encoded_end) goto invalid_size;
Fill_IMA_ADPCM_block(decoded, encoded,
c, channels, &state[c]);
encoded += 4;
@@ -398,6 +401,10 @@ static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
}
SDL_free(freeable);
return(0);
+invalid_size:
+ SDL_SetError("Unexpected chunk length for an IMA ADPCM decoder");
+ SDL_free(freeable);
+ return(-1);
}
SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,
--
2.20.1
From e1f80cadb079e35103e6eebf160a818815c823df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 14 Feb 2019 14:51:52 +0100
Subject: [PATCH] CVE-2019-7575: Fix a buffer overwrite in MS_ADPCM_decode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a WAV format defines shorter audio stream and decoded MS ADPCM data chunk
is longer, decoding continued past the output audio buffer.
This fix is based on a patch from
<https://bugzilla.libsdl.org/show_bug.cgi?id=4492>.
https://bugzilla.libsdl.org/show_bug.cgi?id=4493
CVE-2019-7575
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index e42d01c..b6c49de 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct MS_ADPCM_decodestate *state[2];
- Uint8 *freeable, *encoded, *encoded_end, *decoded;
+ Uint8 *freeable, *encoded, *encoded_end, *decoded, *decoded_end;
Sint32 encoded_len, samplesleft;
Sint8 nybble, stereo;
Sint16 *coeff[2];
@@ -135,6 +135,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
return(-1);
}
decoded = *audio_buf;
+ decoded_end = decoded + *audio_len;
/* Get ready... Go! */
stereo = (MS_ADPCM_state.wavefmt.channels == 2);
@@ -142,7 +143,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
state[1] = &MS_ADPCM_state.state[stereo];
while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
/* Grab the initial information for this block */
- if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
+ if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto invalid_size;
state[0]->hPredictor = *encoded++;
if ( stereo ) {
state[1]->hPredictor = *encoded++;
@@ -169,6 +170,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
/* Store the two initial samples we start with */
+ if (decoded + 4 + (stereo ? 4 : 0) > decoded_end) goto invalid_size;
decoded[0] = state[0]->iSamp2&0xFF;
decoded[1] = state[0]->iSamp2>>8;
decoded += 2;
@@ -190,7 +192,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
MS_ADPCM_state.wavefmt.channels;
while ( samplesleft > 0 ) {
- if (encoded + 1 > encoded_end) goto too_short;
+ if (encoded + 1 > encoded_end) goto invalid_size;
+ if (decoded + 4 > decoded_end) goto invalid_size;
nybble = (*encoded)>>4;
new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
@@ -213,8 +216,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
}
SDL_free(freeable);
return(0);
-too_short:
- SDL_SetError("Too short chunk for a MS ADPCM decoder");
+invalid_size:
+ SDL_SetError("Unexpected chunk length for a MS ADPCM decoder");
SDL_free(freeable);
return(-1);
}
--
2.20.1
From ac3d0d365b1f01a6782565feda0c7432a5795671 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 14 Feb 2019 14:12:22 +0100
Subject: [PATCH] CVE-2019-7577: Fix a buffer overread in MS_ADPCM_decode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If RIFF/WAV data chunk length is shorter then expected for an audio
format defined in preceeding RIFF/WAV format headers, a buffer
overread can happen.
This patch fixes it by checking a MS ADPCM data to be decoded are not
past the initialized buffer.
CVE-2019-7577
Reproducer: https://bugzilla.libsdl.org/show_bug.cgi?id=4492
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index b4ad6c7..e42d01c 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -115,7 +115,7 @@ static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct MS_ADPCM_decodestate *state[2];
- Uint8 *freeable, *encoded, *decoded;
+ Uint8 *freeable, *encoded, *encoded_end, *decoded;
Sint32 encoded_len, samplesleft;
Sint8 nybble, stereo;
Sint16 *coeff[2];
@@ -124,6 +124,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
/* Allocate the proper sized output buffer */
encoded_len = *audio_len;
encoded = *audio_buf;
+ encoded_end = encoded + encoded_len;
freeable = *audio_buf;
*audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) *
MS_ADPCM_state.wSamplesPerBlock*
@@ -141,6 +142,7 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
state[1] = &MS_ADPCM_state.state[stereo];
while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
/* Grab the initial information for this block */
+ if (encoded + 7 + (stereo ? 7 : 0) > encoded_end) goto too_short;
state[0]->hPredictor = *encoded++;
if ( stereo ) {
state[1]->hPredictor = *encoded++;
@@ -188,6 +190,8 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
MS_ADPCM_state.wavefmt.channels;
while ( samplesleft > 0 ) {
+ if (encoded + 1 > encoded_end) goto too_short;
+
nybble = (*encoded)>>4;
new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
decoded[0] = new_sample&0xFF;
@@ -209,6 +213,10 @@ static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
}
SDL_free(freeable);
return(0);
+too_short:
+ SDL_SetError("Too short chunk for a MS ADPCM decoder");
+ SDL_free(freeable);
+ return(-1);
}
struct IMA_ADPCM_decodestate {
--
2.20.1
From 0eb76f6cabcffa2104e34c26e0f41e6de95356ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 15 Feb 2019 10:56:59 +0100
Subject: [PATCH] CVE-2019-7578: Fix a buffer overread in InitIMA_ADPCM
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If IMA ADPCM format chunk was too short, InitIMA_ADPCM() parsing it
could read past the end of chunk data. This patch fixes it.
CVE-2019-7578
https://bugzilla.libsdl.org/show_bug.cgi?id=4494
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 1d446ed..08f65cb 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -240,11 +240,12 @@ static struct IMA_ADPCM_decoder {
struct IMA_ADPCM_decodestate state[2];
} IMA_ADPCM_state;
-static int InitIMA_ADPCM(WaveFMT *format)
+static int InitIMA_ADPCM(WaveFMT *format, int length)
{
- Uint8 *rogue_feel;
+ Uint8 *rogue_feel, *rogue_feel_end;
/* Set the rogue pointer to the IMA_ADPCM specific data */
+ if (length < sizeof(*format)) goto too_short;
IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
@@ -253,11 +254,16 @@ static int InitIMA_ADPCM(WaveFMT *format)
IMA_ADPCM_state.wavefmt.bitspersample =
SDL_SwapLE16(format->bitspersample);
rogue_feel = (Uint8 *)format+sizeof(*format);
+ rogue_feel_end = (Uint8 *)format + length;
if ( sizeof(*format) == 16 ) {
rogue_feel += sizeof(Uint16);
}
+ if (rogue_feel + 2 > rogue_feel_end) goto too_short;
IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
return(0);
+too_short:
+ SDL_SetError("Unexpected length of a chunk with an IMA ADPCM format");
+ return(-1);
}
static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble)
@@ -500,7 +506,7 @@ SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,
break;
case IMA_ADPCM_CODE:
/* Try to understand this */
- if ( InitIMA_ADPCM(format) < 0 ) {
+ if ( InitIMA_ADPCM(format, lenread) < 0 ) {
was_error = 1;
goto done;
}
--
2.20.1
CVE-2019-7635: Reject BMP images with pixel colors out the palette
If a 1-, 4-, or 8-bit per pixel BMP image declares less used colors
than the palette offers an SDL_Surface with a palette of the indicated
number of used colors is created. If some of the image's pixel
refer to a color number higher then the maximal used colors, a subsequent
bliting operation on the surface will look up a color past a blit map
(that is based on the palette) memory. I.e. passing such SDL_Surface
to e.g. an SDL_DisplayFormat() function will result in a buffer overread in
a blit function.
This patch fixes it by validing each pixel's color to be less than the
maximal color number in the palette. A validation failure raises an
error from a SDL_LoadBMP_RW() function.
CVE-2019-7635
https://bugzilla.libsdl.org/show_bug.cgi?id=4498
Signed-off-by: Petr Písař <ppisar@redhat.com>
diff -r a936f9bd3e38 -r f1f5878be5db src/video/SDL_bmp.c
--- a/src/video/SDL_bmp.c Mon Jun 10 09:25:05 2019 -0700
+++ b/src/video/SDL_bmp.c Tue Jun 11 06:28:12 2019 -0700
@@ -308,6 +308,12 @@
}
*(bits+i) = (pixel>>shift);
pixel <<= ExpandBMP;
+ if ( bits[i] >= biClrUsed ) {
+ SDL_SetError(
+ "A BMP image contains a pixel with a color out of the palette");
+ was_error = SDL_TRUE;
+ goto done;
+ }
} }
break;
@@ -318,6 +324,16 @@
was_error = SDL_TRUE;
goto done;
}
+ if ( 8 == biBitCount && palette && biClrUsed < (1 << biBitCount ) ) {
+ for ( i=0; i<surface->w; ++i ) {
+ if ( bits[i] >= biClrUsed ) {
+ SDL_SetError(
+ "A BMP image contains a pixel with a color out of the palette");
+ was_error = SDL_TRUE;
+ goto done;
+ }
+ }
+ }
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
/* Byte-swap the pixels if needed. Note that the 24bpp
case has already been taken care of above. */
Fixed bug 4500 - Heap-Buffer Overflow in Map1toN pertaining to SDL_pixels.c
Petr Pisar
The reproducer has these data in BITMAPINFOHEADER:
biSize = 40
biBitCount = 8
biClrUsed = 131075
SDL_LoadBMP_RW() function passes biBitCount as a color depth to SDL_CreateRGBSurface(), thus 256-color pallete is allocated. But then biClrUsed colors are read from a file and stored into the palette. SDL_LoadBMP_RW should report an error if biClrUsed is greater than 2^biBitCount.
Also fixes CVE-2019-7638
diff -r 8586f153eede -r 19d8c3b9c251 src/video/SDL_bmp.c
--- a/src/video/SDL_bmp.c Sun Jan 13 15:27:50 2019 +0100
+++ b/src/video/SDL_bmp.c Mon Feb 18 07:48:23 2019 -0800
@@ -233,6 +233,10 @@
if ( palette ) {
if ( biClrUsed == 0 ) {
biClrUsed = 1 << biBitCount;
+ } else if ( biClrUsed > (1 << biBitCount) ) {
+ SDL_SetError("BMP file has an invalid number of colors");
+ was_error = SDL_TRUE;
+ goto done;
}
if ( biSize == 12 ) {
for ( i = 0; i < (int)biClrUsed; ++i ) {
CVE-2019-7637: Fix in integer overflow in SDL_CalculatePitch
If a too large width is passed to SDL_SetVideoMode() the width travels
to SDL_CalculatePitch() where the width (e.g. 65535) is multiplied by
BytesPerPixel (e.g. 4) and the result is stored into Uint16 pitch
variable. During this arithmetics an integer overflow can happen (e.g.
the value is clamped as 65532). As a result SDL_Surface with a pitch
smaller than width * BytesPerPixel is created, too small pixel buffer
is allocated and when the SDL_Surface is processed in SDL_FillRect()
a buffer overflow occurs.
This can be reproduced with "./graywin -width 21312312313123213213213"
command.
This patch fixes is by using a very careful arithmetics in
SDL_CalculatePitch(). If an overflow is detected, an error is reported
back as a special 0 value. We assume that 0-width surfaces do not
occur in the wild. Since SDL_CalculatePitch() is a private function,
we can change the semantics.
CVE-2019-7637
https://bugzilla.libsdl.org/show_bug.cgi?id=4497
Signed-off-by: Petr Písař <ppisar@redhat.com>
diff -r 4646533663ae -r 9b0e5c555c0f src/video/SDL_pixels.c
--- a/src/video/SDL_pixels.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/SDL_pixels.c Sat Mar 16 19:16:24 2019 -0700
@@ -286,26 +286,53 @@
}
}
/*
- * Calculate the pad-aligned scanline width of a surface
+ * Calculate the pad-aligned scanline width of a surface. Return 0 in case of
+ * an error.
*/
Uint16 SDL_CalculatePitch(SDL_Surface *surface)
{
- Uint16 pitch;
+ unsigned int pitch = 0;
/* Surface should be 4-byte aligned for speed */
- pitch = surface->w*surface->format->BytesPerPixel;
+ /* The code tries to prevent from an Uint16 overflow. */;
+ for (Uint8 byte = surface->format->BytesPerPixel; byte; byte--) {
+ pitch += (unsigned int)surface->w;
+ if (pitch < surface->w) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ }
switch (surface->format->BitsPerPixel) {
case 1:
- pitch = (pitch+7)/8;
+ if (pitch % 8) {
+ pitch = pitch / 8 + 1;
+ } else {
+ pitch = pitch / 8;
+ }
break;
case 4:
- pitch = (pitch+1)/2;
+ if (pitch % 2) {
+ pitch = pitch / 2 + 1;
+ } else {
+ pitch = pitch / 2;
+ }
break;
default:
break;
}
- pitch = (pitch + 3) & ~3; /* 4-byte aligning */
- return(pitch);
+ /* 4-byte aligning */
+ if (pitch & 3) {
+ if (pitch + 3 < pitch) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ pitch = (pitch + 3) & ~3;
+ }
+ if (pitch > 0xFFFF) {
+ SDL_SetError("A scanline is too wide");
+ return(0);
+ }
+ return((Uint16)pitch);
}
/*
* Match an RGB value to a particular palette index
diff -r 4646533663ae -r 9b0e5c555c0f src/video/gapi/SDL_gapivideo.c
--- a/src/video/gapi/SDL_gapivideo.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/gapi/SDL_gapivideo.c Sat Mar 16 19:16:24 2019 -0700
@@ -733,6 +733,9 @@
video->w = gapi->w = width;
video->h = gapi->h = height;
video->pitch = SDL_CalculatePitch(video);
+ if (!current->pitch) {
+ return(NULL);
+ }
/* Small fix for WinCE/Win32 - when activating window
SDL_VideoSurface is equal to zero, so activating code
diff -r 4646533663ae -r 9b0e5c555c0f src/video/nanox/SDL_nxvideo.c
--- a/src/video/nanox/SDL_nxvideo.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/nanox/SDL_nxvideo.c Sat Mar 16 19:16:24 2019 -0700
@@ -378,6 +378,10 @@
current -> w = width ;
current -> h = height ;
current -> pitch = SDL_CalculatePitch (current) ;
+ if (!current->pitch) {
+ current = NULL;
+ goto done;
+ }
NX_ResizeImage (this, current, flags) ;
}
diff -r 4646533663ae -r 9b0e5c555c0f src/video/ps2gs/SDL_gsvideo.c
--- a/src/video/ps2gs/SDL_gsvideo.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/ps2gs/SDL_gsvideo.c Sat Mar 16 19:16:24 2019 -0700
@@ -479,6 +479,9 @@
current->w = width;
current->h = height;
current->pitch = SDL_CalculatePitch(current);
+ if (!current->pitch) {
+ return(NULL);
+ }
/* Memory map the DMA area for block memory transfer */
if ( ! mapped_mem ) {
diff -r 4646533663ae -r 9b0e5c555c0f src/video/ps3/SDL_ps3video.c
--- a/src/video/ps3/SDL_ps3video.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/ps3/SDL_ps3video.c Sat Mar 16 19:16:24 2019 -0700
@@ -339,6 +339,9 @@
current->w = width;
current->h = height;
current->pitch = SDL_CalculatePitch(current);
+ if (!current->pitch) {
+ return(NULL);
+ }
/* Alloc aligned mem for current->pixels */
s_pixels = memalign(16, current->h * current->pitch);
diff -r 4646533663ae -r 9b0e5c555c0f src/video/windib/SDL_dibvideo.c
--- a/src/video/windib/SDL_dibvideo.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/windib/SDL_dibvideo.c Sat Mar 16 19:16:24 2019 -0700
@@ -675,6 +675,9 @@
video->w = width;
video->h = height;
video->pitch = SDL_CalculatePitch(video);
+ if (!current->pitch) {
+ return(NULL);
+ }
/* Small fix for WinCE/Win32 - when activating window
SDL_VideoSurface is equal to zero, so activating code
diff -r 4646533663ae -r 9b0e5c555c0f src/video/windx5/SDL_dx5video.c
--- a/src/video/windx5/SDL_dx5video.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/windx5/SDL_dx5video.c Sat Mar 16 19:16:24 2019 -0700
@@ -1127,6 +1127,9 @@
video->w = width;
video->h = height;
video->pitch = SDL_CalculatePitch(video);
+ if (!current->pitch) {
+ return(NULL);
+ }
#ifndef NO_CHANGEDISPLAYSETTINGS
/* Set fullscreen mode if appropriate.
diff -r 4646533663ae -r 9b0e5c555c0f src/video/x11/SDL_x11video.c
--- a/src/video/x11/SDL_x11video.c Sat Mar 16 18:35:33 2019 -0700
+++ b/src/video/x11/SDL_x11video.c Sat Mar 16 19:16:24 2019 -0700
@@ -1225,6 +1225,10 @@
current->w = width;
current->h = height;
current->pitch = SDL_CalculatePitch(current);
+ if (!current->pitch) {
+ current = NULL;
+ goto done;
+ }
if (X11_ResizeImage(this, current, flags) < 0) {
current = NULL;
goto done;
From bb11ffcff5ae2f25bead921c2a299e7e63d8a759 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 14 Feb 2019 16:51:54 +0100
Subject: [PATCH] CVE-2019-7572: Fix a buffer overread in IMA_ADPCM_nibble
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If an IMA ADPCM block contained an initial index out of step table
range (loaded in IMA_ADPCM_decode()), IMA_ADPCM_nibble() blindly used
this bogus value and that lead to a buffer overread.
This patch fixes it by moving clamping the index value at the
beginning of IMA_ADPCM_nibble() function instead of the end after
an update.
CVE-2019-7572
https://bugzilla.libsdl.org/show_bug.cgi?id=4495
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
src/audio/SDL_wave.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c
index 2968b3d..69d62dc 100644
--- a/src/audio/SDL_wave.c
+++ b/src/audio/SDL_wave.c
@@ -275,6 +275,14 @@ static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble)
};
Sint32 delta, step;
+ /* Clamp index value. The inital value can be invalid. */
+ if ( state->index > 88 ) {
+ state->index = 88;
+ } else
+ if ( state->index < 0 ) {
+ state->index = 0;
+ }
+
/* Compute difference and new sample value */
step = step_table[state->index];