aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg@britannica.bec.de>2011-08-21 18:51:53 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-16 10:29:36 +0100
commit65deb86f8dab0c88e051b5ac416b7907433aa849 (patch)
tree9ae30435d3722d0e5245841e8c3d344d6aae94d2
parent18e337ddf410accec5bdf18c5d28bbd5f3ace7cb (diff)
downloadnx-libs-65deb86f8dab0c88e051b5ac416b7907433aa849.tar.gz
nx-libs-65deb86f8dab0c88e051b5ac416b7907433aa849.tar.bz2
nx-libs-65deb86f8dab0c88e051b5ac416b7907433aa849.zip
Do proper input validation to fix for CVE-2011-2895.
It ensures that all valid input can be decompressed, checks that the overflow conditions doesn't happen and generally tightens the validation of the LZW stream and doesn't pessimize the inner loop for no good reason. It's derived from a change in libarchive from 2004. v2: backports to nx-libs 3.6.x (Mihai Moldovan) v3: fix comment lines starting with "+" + whitespace fixes (Mike Gabriel) Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr> Reviewed-by: Tomas Hoger <thoger@redhat.com>
-rw-r--r--nx-X11/lib/font/fontfile/decompress.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/nx-X11/lib/font/fontfile/decompress.c b/nx-X11/lib/font/fontfile/decompress.c
index 553b31585..c7e649f91 100644
--- a/nx-X11/lib/font/fontfile/decompress.c
+++ b/nx-X11/lib/font/fontfile/decompress.c
@@ -99,7 +99,7 @@ static char_type magic_header[] = { "\037\235" }; /* 1F 9D */
#define FIRST 257 /* first free entry */
#define CLEAR 256 /* table clear output code */
-#define STACK_SIZE 8192
+#define STACK_SIZE 65300
typedef struct _compressedFILE {
BufFilePtr file;
@@ -180,14 +180,12 @@ BufFilePushCompressed (BufFilePtr f)
file->tab_suffix[code] = (char_type) code;
}
file->free_ent = ((file->block_compress) ? FIRST : 256 );
+ file->oldcode = -1;
file->clear_flg = 0;
file->offset = 0;
file->size = 0;
file->stackp = file->de_stack;
bzero(file->buf, BITS);
- file->finchar = file->oldcode = getcode (file);
- if (file->oldcode != -1)
- *file->stackp++ = file->finchar;
return BufFileCreate ((char *) file,
BufCompressedFill,
0,
@@ -232,9 +230,6 @@ BufCompressedFill (BufFilePtr f)
if (buf == bufend)
break;
- if (oldcode == -1)
- break;
-
code = getcode (file);
if (code == -1)
break;
@@ -243,26 +238,34 @@ BufCompressedFill (BufFilePtr f)
for ( code = 255; code >= 0; code-- )
file->tab_prefix[code] = 0;
file->clear_flg = 1;
- file->free_ent = FIRST - 1;
- if ( (code = getcode (file)) == -1 ) /* O, untimely death! */
- break;
+ file->free_ent = FIRST;
+ oldcode = -1;
+ continue;
}
incode = code;
/*
* Special case for KwKwK string.
*/
if ( code >= file->free_ent ) {
+ if ( code > file->free_ent || oldcode == -1 ) {
+ /* Bad stream. */
+ return BUFFILEEOF;
+ }
*stackp++ = finchar;
code = oldcode;
}
-
+ /*
+ * The above condition ensures that code < free_ent.
+ * The construction of tab_prefixof in turn guarantees that
+ * each iteration decreases code and therefore stack usage is
+ * bound by 1 << BITS - 256.
+ */
+
/*
* Generate output characters in reverse order
*/
while ( code >= 256 )
{
- if (stackp - de_stack >= STACK_SIZE - 1)
- return BUFFILEEOF;
*stackp++ = file->tab_suffix[code];
code = file->tab_prefix[code];
}
@@ -272,7 +275,7 @@ BufCompressedFill (BufFilePtr f)
/*
* Generate the new entry.
*/
- if ( (code=file->free_ent) < file->maxmaxcode ) {
+ if ( (code=file->free_ent) < file->maxmaxcode && oldcode != -1) {
file->tab_prefix[code] = (unsigned short)oldcode;
file->tab_suffix[code] = finchar;
file->free_ent = code+1;