Blame SOURCES/0002-Fix-CVE-2022-44617-Runaway-loop-with-width-of-0-and-.patch

f8f308
From 0a1959b3b061d2e6d0a512e83035d84e5828f388 Mon Sep 17 00:00:00 2001
f8f308
From: Alan Coopersmith <alan.coopersmith@oracle.com>
f8f308
Date: Sat, 7 Jan 2023 12:44:28 -0800
f8f308
Subject: [PATCH libXpm 2/6] Fix CVE-2022-44617: Runaway loop with width of 0
f8f308
 and enormous height
f8f308
f8f308
When reading XPM images from a file with libXpm 3.5.14 or older, if a
f8f308
image has a width of 0 and a very large height, the ParsePixels() function
f8f308
will loop over the entire height calling getc() and ungetc() repeatedly,
f8f308
or in some circumstances, may loop seemingly forever, which may cause a
f8f308
denial of service to the calling program when given a small crafted XPM
f8f308
file to parse.
f8f308
f8f308
Closes: #2
f8f308
f8f308
Reported-by: Martin Ettl <ettl.martin78@googlemail.com>
f8f308
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
f8f308
---
f8f308
 src/data.c  | 20 ++++++++++++++------
f8f308
 src/parse.c | 31 +++++++++++++++++++++++++++----
f8f308
 2 files changed, 41 insertions(+), 10 deletions(-)
f8f308
f8f308
diff --git a/src/data.c b/src/data.c
f8f308
index bfad4ff..7524e65 100644
f8f308
--- a/src/data.c
f8f308
+++ b/src/data.c
f8f308
@@ -195,19 +195,23 @@ xpmNextString(xpmData *data)
f8f308
 	register char c;
f8f308
 
f8f308
 	/* get to the end of the current string */
f8f308
-	if (data->Eos)
f8f308
-	    while ((c = *data->cptr++) && c != data->Eos);
f8f308
+	if (data->Eos) {
f8f308
+	    while ((c = *data->cptr++) && c != data->Eos && c != '\0');
f8f308
+
f8f308
+	    if (c == '\0')
f8f308
+		return XpmFileInvalid;
f8f308
+	}
f8f308
 
f8f308
 	/*
f8f308
 	 * then get to the beginning of the next string looking for possible
f8f308
 	 * comment
f8f308
 	 */
f8f308
 	if (data->Bos) {
f8f308
-	    while ((c = *data->cptr++) && c != data->Bos)
f8f308
+	    while ((c = *data->cptr++) && c != data->Bos && c != '\0')
f8f308
 		if (data->Bcmt && c == data->Bcmt[0])
f8f308
 		    ParseComment(data);
f8f308
 	} else if (data->Bcmt) {	/* XPM2 natural */
f8f308
-	    while ((c = *data->cptr++) == data->Bcmt[0])
f8f308
+	    while (((c = *data->cptr++) == data->Bcmt[0]) && c != '\0')
f8f308
 		ParseComment(data);
f8f308
 	    data->cptr--;
f8f308
 	}
f8f308
@@ -216,9 +220,13 @@ xpmNextString(xpmData *data)
f8f308
 	FILE *file = data->stream.file;
f8f308
 
f8f308
 	/* get to the end of the current string */
f8f308
-	if (data->Eos)
f8f308
+	if (data->Eos) {
f8f308
 	    while ((c = Getc(data, file)) != data->Eos && c != EOF);
f8f308
 
f8f308
+	    if (c == EOF)
f8f308
+		return XpmFileInvalid;
f8f308
+	}
f8f308
+
f8f308
 	/*
f8f308
 	 * then get to the beginning of the next string looking for possible
f8f308
 	 * comment
f8f308
@@ -234,7 +242,7 @@ xpmNextString(xpmData *data)
f8f308
 	    Ungetc(data, c, file);
f8f308
 	}
f8f308
     }
f8f308
-    return 0;
f8f308
+    return XpmSuccess;
f8f308
 }
f8f308
 
f8f308
 
f8f308
diff --git a/src/parse.c b/src/parse.c
f8f308
index 613529e..606789d 100644
f8f308
--- a/src/parse.c
f8f308
+++ b/src/parse.c
f8f308
@@ -427,6 +427,13 @@ ParsePixels(
f8f308
 {
f8f308
     unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */
f8f308
     unsigned int a, x, y;
f8f308
+    int ErrorStatus;
f8f308
+
f8f308
+    if ((width == 0) && (height != 0))
f8f308
+	return (XpmFileInvalid);
f8f308
+
f8f308
+    if ((height == 0) && (width != 0))
f8f308
+	return (XpmFileInvalid);
f8f308
 
f8f308
     if ((height > 0 && width >= UINT_MAX / height) ||
f8f308
 	width * height >= UINT_MAX / sizeof(unsigned int))
f8f308
@@ -464,7 +471,11 @@ ParsePixels(
f8f308
 		colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
f8f308
 
f8f308
 	    for (y = 0; y < height; y++) {
f8f308
-		xpmNextString(data);
f8f308
+		ErrorStatus = xpmNextString(data);
f8f308
+		if (ErrorStatus != XpmSuccess) {
f8f308
+		    XpmFree(iptr2);
f8f308
+		    return (ErrorStatus);
f8f308
+		}
f8f308
 		for (x = 0; x < width; x++, iptr++) {
f8f308
 		    int c = xpmGetC(data);
f8f308
 
f8f308
@@ -511,7 +522,11 @@ do \
f8f308
 	    }
f8f308
 
f8f308
 	    for (y = 0; y < height; y++) {
f8f308
-		xpmNextString(data);
f8f308
+		ErrorStatus = xpmNextString(data);
f8f308
+		if (ErrorStatus != XpmSuccess) {
f8f308
+		    XpmFree(iptr2);
f8f308
+		    return (ErrorStatus);
f8f308
+		}
f8f308
 		for (x = 0; x < width; x++, iptr++) {
f8f308
 		    int cc1 = xpmGetC(data);
f8f308
 		    if (cc1 > 0 && cc1 < 256) {
f8f308
@@ -551,7 +566,11 @@ do \
f8f308
 		xpmHashAtom *slot;
f8f308
 
f8f308
 		for (y = 0; y < height; y++) {
f8f308
-		    xpmNextString(data);
f8f308
+		    ErrorStatus = xpmNextString(data);
f8f308
+		    if (ErrorStatus != XpmSuccess) {
f8f308
+			XpmFree(iptr2);
f8f308
+			return (ErrorStatus);
f8f308
+		    }
f8f308
 		    for (x = 0; x < width; x++, iptr++) {
f8f308
 			for (a = 0, s = buf; a < cpp; a++, s++) {
f8f308
 			    int c = xpmGetC(data);
f8f308
@@ -571,7 +590,11 @@ do \
f8f308
 		}
f8f308
 	    } else {
f8f308
 		for (y = 0; y < height; y++) {
f8f308
-		    xpmNextString(data);
f8f308
+		    ErrorStatus = xpmNextString(data);
f8f308
+		    if (ErrorStatus != XpmSuccess) {
f8f308
+			XpmFree(iptr2);
f8f308
+			return (ErrorStatus);
f8f308
+		    }
f8f308
 		    for (x = 0; x < width; x++, iptr++) {
f8f308
 			for (a = 0, s = buf; a < cpp; a++, s++) {
f8f308
 			    int c = xpmGetC(data);
f8f308
-- 
f8f308
2.39.0
f8f308