1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
From: Sam Lantinga <slouken@libsdl.org>
Date: Sun, 5 Dec 2021 11:11:54 +0000
Subject: Fixed TALOS-2019-0841, heap buffer overlow exploit
Also fixed loading some images with incorrect palette location
Bug: https://security-tracker.debian.org/tracker/CVE-2019-12218
Origin: backport, 2.0.5, commit:7453e79c8cdb, commit:https://github.com/libsdl-org/SDL_image/commit/782d29a101351cf48c9e9f42e625f76027a93c5d
---
IMG_pcx.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/IMG_pcx.c b/IMG_pcx.c
index 9f92a46..424810c 100644
--- a/IMG_pcx.c
+++ b/IMG_pcx.c
@@ -100,6 +100,8 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
Uint8 *row, *buf = NULL;
char *error = NULL;
int bits, src_bits;
+ int count = 0;
+ Uint8 ch;
if ( !src ) {
/* The error message has been set in SDL_RWFromFile */
@@ -148,14 +150,14 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
bpl = pcxh.NPlanes * pcxh.BytesPerLine;
if (bpl > surface->pitch) {
error = "bytes per line is too large (corrupt?)";
+ goto done;
}
- buf = calloc(SDL_max(bpl, surface->pitch), 1);
+ buf = (Uint8 *)SDL_calloc(surface->pitch, 1);
row = surface->pixels;
for ( y=0; y<surface->h; ++y ) {
/* decode a scan line to a temporary buffer first */
- int i, count = 0;
- Uint8 ch;
- Uint8 *dst = (src_bits == 8) ? row : buf;
+ int i;
+ Uint8 *dst = buf;
if ( pcxh.Encoding == 0 ) {
if(!SDL_RWread(src, dst, bpl, 1)) {
error = "file truncated";
@@ -168,14 +170,15 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
error = "file truncated";
goto done;
}
- if( (ch & 0xc0) == 0xc0) {
- count = ch & 0x3f;
+ if( ch < 0xc0) {
+ count = 1;
+ } else {
+ count = ch - 0xc0;
if(!SDL_RWread(src, &ch, 1, 1)) {
error = "file truncated";
goto done;
}
- } else
- count = 1;
+ }
}
dst[i] = ch;
count--;
@@ -207,10 +210,16 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
int x;
dst = row + plane;
for(x = 0; x < width; x++) {
+ if ( dst >= row+surface->pitch ) {
+ error = "decoding out of bounds (corrupt?)";
+ goto done;
+ }
*dst = *src++;
dst += pcxh.NPlanes;
}
}
+ } else {
+ SDL_memcpy(row, buf, bpl);
}
row += surface->pitch;
@@ -227,8 +236,9 @@ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src)
/* look for a 256-colour palette */
do {
if ( !SDL_RWread(src, &ch, 1, 1)) {
- error = "file truncated";
- goto done;
+ /* Couldn't find the palette, try the end of the file */
+ SDL_RWseek(src, -768, RW_SEEK_END);
+ break;
}
} while ( ch != 12 );
|