https://bugs.gentoo.org/900763 CVE-2022-44617 Patch ported from the following commits for libXpm: From f80fa6ae47ad4a5beacb287c0030c9913b046643 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Sat, 7 Jan 2023 12:44:28 -0800 Subject: [PATCH] Fix CVE-2022-44617: Runaway loop with width of 0 and enormous height From c5ab17bcc34914c0b0707d2135dbebe9a367c5f0 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Thu, 12 Jan 2023 15:05:39 +1000 Subject: [PATCH] Prevent a double free in the error code path --- motif-2.3.8/lib/Xm/Xpmcreate.c +++ motif-2.3.8/lib/Xm/Xpmcreate.c @@ -954,10 +954,14 @@ #ifndef FOR_MSW if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) { XDestroyImage(*image_return); + *image_return = NULL; return (XpmNoMemory); } - if((*image_return)->bytes_per_line == 0 || height == 0) + if((*image_return)->bytes_per_line == 0 || height == 0) { + XDestroyImage(*image_return); + *image_return = NULL; return XpmNoMemory; + } /* now that bytes_per_line must have been set properly alloc data */ (*image_return)->data = (char *) XpmMalloc((*image_return)->bytes_per_line * height); --- motif-2.3.8/lib/Xm/Xpmdata.c +++ motif-2.3.8/lib/Xm/Xpmdata.c @@ -193,19 +193,23 @@ register char c; /* get to the end of the current string */ - if (mdata->Eos) - while ((c = *mdata->cptr++) && c != mdata->Eos); + if (mdata->Eos) { + while ((c = *mdata->cptr++) && c != mdata->Eos && c != '\0'); + + if (c == '\0') + return XpmFileInvalid; + } /* * then get to the beginning of the next string looking for possible * comment */ if (mdata->Bos) { - while ((c = *mdata->cptr++) && c != mdata->Bos) + while ((c = *mdata->cptr++) && c != mdata->Bos && c != '\0') if (mdata->Bcmt && c == mdata->Bcmt[0]) ParseComment(mdata); } else if (mdata->Bcmt) { /* XPM2 natural */ - while ((c = *mdata->cptr++) == mdata->Bcmt[0]) + while (((c = *mdata->cptr++) == mdata->Bcmt[0]) && c != '\0') ParseComment(mdata); mdata->cptr--; } @@ -214,9 +218,13 @@ FILE *file = mdata->stream.file; /* get to the end of the current string */ - if (mdata->Eos) + if (mdata->Eos) { while ((c = getc(file)) != mdata->Eos && c != EOF); + if (c == EOF) + return XpmFileInvalid; + } + /* * then get to the beginning of the next string looking for possible * comment @@ -232,7 +240,7 @@ ungetc(c, file); } } - return 0; + return XpmSuccess; } --- motif-2.3.8/lib/Xm/Xpmparse.c +++ motif-2.3.8/lib/Xm/Xpmparse.c @@ -523,6 +523,13 @@ { unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */ unsigned int a, x, y; + int ErrorStatus; + + if ((width == 0) && (height != 0)) + return (XpmFileInvalid); + + if ((height == 0) && (width != 0)) + return (XpmFileInvalid); if ((height > 0 && width >= UINT_MAX / height) || width * height >= UINT_MAX / sizeof(unsigned int)) @@ -560,7 +567,11 @@ colidx[(unsigned char)colorTable[a].string[0]] = a + 1; for (y = 0; y < height; y++) { - xpmNextString(data); + ErrorStatus = xpmNextString(data); + if (ErrorStatus != XpmSuccess) { + XpmFree(iptr2); + return (ErrorStatus); + } for (x = 0; x < width; x++, iptr++) { int c = xpmGetC(data); @@ -607,7 +618,11 @@ } for (y = 0; y < height; y++) { - xpmNextString(data); + ErrorStatus = xpmNextString(data); + if (ErrorStatus != XpmSuccess) { + XpmFree(iptr2); + return (ErrorStatus); + } for (x = 0; x < width; x++, iptr++) { int cc1 = xpmGetC(data); if (cc1 > 0 && cc1 < 256) { @@ -646,7 +661,11 @@ xpmHashAtom *slot; for (y = 0; y < height; y++) { - xpmNextString(data); + ErrorStatus = xpmNextString(data); + if (ErrorStatus != XpmSuccess) { + XpmFree(iptr2); + return (ErrorStatus); + } for (x = 0; x < width; x++, iptr++) { for (a = 0, s = buf; a < cpp; a++, s++) *s = xpmGetC(data); /* int assigned to char, not a problem here */ @@ -660,7 +679,11 @@ } } else { for (y = 0; y < height; y++) { - xpmNextString(data); + ErrorStatus = xpmNextString(data); + if (ErrorStatus != XpmSuccess) { + XpmFree(iptr2); + return (ErrorStatus); + } for (x = 0; x < width; x++, iptr++) { for (a = 0, s = buf; a < cpp; a++, s++) *s = xpmGetC(data); /* int assigned to char, not a problem here */