a3c0591d4a
Includes hardening for CVE-2023-43786 and CVE-2023-43787. Check X.Org Security Advisory [1] for more information. [1] https://lists.x.org/archives/xorg-announce/2023-October/003424.html Resolves: https://issues.redhat.com/browse/RHEL-12414
285 lines
8.2 KiB
Diff
285 lines
8.2 KiB
Diff
From 84fb14574c039f19ad7face87eb9acc31a50701c Mon Sep 17 00:00:00 2001
|
|
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
Date: Wed, 6 Sep 2023 17:34:33 -0700
|
|
Subject: [PATCH] Avoid CVE-2023-43786: stack exhaustion in XPutImage()
|
|
|
|
This doesn't fix the CVE - that has to happen in libX11, this
|
|
just tries to avoid triggering it from libXpm, and saves time
|
|
in not pretending we can successfully create an X11 pixmap with
|
|
dimensions larger than the unsigned 16-bit integers used in the
|
|
X11 protocol for the dimensions.
|
|
|
|
Reported by Yair Mizrahi of the JFrog Vulnerability Research team
|
|
|
|
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
|
---
|
|
src/CrPFrBuf.c | 28 +++++++++++++++++++++++-----
|
|
src/CrPFrDat.c | 31 +++++++++++++++++++++++--------
|
|
src/CrPFrI.c | 10 +++++++++-
|
|
src/RdFToP.c | 28 +++++++++++++++++++++++-----
|
|
src/XpmI.h | 2 +-
|
|
src/create.c | 28 +++++++++++++++++++++++-----
|
|
6 files changed, 102 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/src/CrPFrBuf.c b/src/CrPFrBuf.c
|
|
index 2c28a41..e9e2243 100644
|
|
--- a/src/CrPFrBuf.c
|
|
+++ b/src/CrPFrBuf.c
|
|
@@ -46,7 +46,7 @@ XpmCreatePixmapFromBuffer(
|
|
Pixmap *shapemask_return,
|
|
XpmAttributes *attributes)
|
|
{
|
|
- XImage *ximage, *shapeimage;
|
|
+ XImage *ximage = NULL, *shapeimage = NULL;
|
|
int ErrorStatus;
|
|
|
|
/* initialize return values */
|
|
@@ -63,16 +63,34 @@ XpmCreatePixmapFromBuffer(
|
|
attributes);
|
|
|
|
if (ErrorStatus < 0) /* fatal error */
|
|
- return (ErrorStatus);
|
|
+ goto cleanup;
|
|
|
|
/* create the pixmaps and destroy images */
|
|
if (pixmap_return && ximage) {
|
|
- xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
- XDestroyImage(ximage);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
+ if (ErrorStatus < 0) /* fatal error */
|
|
+ goto cleanup;
|
|
}
|
|
if (shapemask_return && shapeimage) {
|
|
- xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ }
|
|
+
|
|
+ cleanup:
|
|
+ if (ximage != NULL)
|
|
+ XDestroyImage(ximage);
|
|
+ if (shapeimage != NULL)
|
|
XDestroyImage(shapeimage);
|
|
+ if (ErrorStatus < 0) {
|
|
+ if (pixmap_return && *pixmap_return) {
|
|
+ XFreePixmap(display, *pixmap_return);
|
|
+ *pixmap_return = 0;
|
|
+ }
|
|
+ if (shapemask_return && *shapemask_return) {
|
|
+ XFreePixmap(display, *shapemask_return);
|
|
+ *shapemask_return = 0;
|
|
+ }
|
|
}
|
|
return (ErrorStatus);
|
|
}
|
|
diff --git a/src/CrPFrDat.c b/src/CrPFrDat.c
|
|
index b65771d..8622663 100644
|
|
--- a/src/CrPFrDat.c
|
|
+++ b/src/CrPFrDat.c
|
|
@@ -46,7 +46,7 @@ XpmCreatePixmapFromData(
|
|
Pixmap *shapemask_return,
|
|
XpmAttributes *attributes)
|
|
{
|
|
- XImage *ximage, *shapeimage;
|
|
+ XImage *ximage = NULL, *shapeimage = NULL;
|
|
int ErrorStatus;
|
|
|
|
/* initialize return values */
|
|
@@ -63,19 +63,34 @@ XpmCreatePixmapFromData(
|
|
attributes);
|
|
|
|
if (ErrorStatus != XpmSuccess)
|
|
- return (ErrorStatus);
|
|
-
|
|
- if (ErrorStatus < 0) /* fatal error */
|
|
- return (ErrorStatus);
|
|
+ goto cleanup;
|
|
|
|
/* create the pixmaps and destroy images */
|
|
if (pixmap_return && ximage) {
|
|
- xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
- XDestroyImage(ximage);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
+ if (ErrorStatus < 0) /* fatal error */
|
|
+ goto cleanup;
|
|
}
|
|
if (shapemask_return && shapeimage) {
|
|
- xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ }
|
|
+
|
|
+ cleanup:
|
|
+ if (ximage != NULL)
|
|
+ XDestroyImage(ximage);
|
|
+ if (shapeimage != NULL)
|
|
XDestroyImage(shapeimage);
|
|
+ if (ErrorStatus < 0) {
|
|
+ if (pixmap_return && *pixmap_return) {
|
|
+ XFreePixmap(display, *pixmap_return);
|
|
+ *pixmap_return = 0;
|
|
+ }
|
|
+ if (shapemask_return && *shapemask_return) {
|
|
+ XFreePixmap(display, *shapemask_return);
|
|
+ *shapemask_return = 0;
|
|
+ }
|
|
}
|
|
return (ErrorStatus);
|
|
}
|
|
diff --git a/src/CrPFrI.c b/src/CrPFrI.c
|
|
index 8f6f4aa..f6688c5 100644
|
|
--- a/src/CrPFrI.c
|
|
+++ b/src/CrPFrI.c
|
|
@@ -36,8 +36,9 @@
|
|
#include <config.h>
|
|
#endif
|
|
#include "XpmI.h"
|
|
+#include <stdint.h>
|
|
|
|
-void
|
|
+int
|
|
xpmCreatePixmapFromImage(
|
|
Display *display,
|
|
Drawable d,
|
|
@@ -47,6 +48,11 @@ xpmCreatePixmapFromImage(
|
|
GC gc;
|
|
XGCValues values;
|
|
|
|
+ /* X Pixmaps are limited to unsigned 16-bit height/width */
|
|
+ if ((ximage->width > UINT16_MAX) || (ximage->height > UINT16_MAX)) {
|
|
+ return XpmNoMemory;
|
|
+ }
|
|
+
|
|
*pixmap_return = XCreatePixmap(display, d, ximage->width,
|
|
ximage->height, ximage->depth);
|
|
/* set fg and bg in case we have an XYBitmap */
|
|
@@ -59,4 +65,6 @@ xpmCreatePixmapFromImage(
|
|
ximage->width, ximage->height);
|
|
|
|
XFreeGC(display, gc);
|
|
+
|
|
+ return XpmSuccess;
|
|
}
|
|
diff --git a/src/RdFToP.c b/src/RdFToP.c
|
|
index f829757..2c3e7f9 100644
|
|
--- a/src/RdFToP.c
|
|
+++ b/src/RdFToP.c
|
|
@@ -46,7 +46,7 @@ XpmReadFileToPixmap(
|
|
Pixmap *shapemask_return,
|
|
XpmAttributes *attributes)
|
|
{
|
|
- XImage *ximage, *shapeimage;
|
|
+ XImage *ximage = NULL, *shapeimage = NULL;
|
|
int ErrorStatus;
|
|
|
|
/* initialize return values */
|
|
@@ -62,16 +62,34 @@ XpmReadFileToPixmap(
|
|
attributes);
|
|
|
|
if (ErrorStatus < 0) /* fatal error */
|
|
- return (ErrorStatus);
|
|
+ goto cleanup;
|
|
|
|
/* create the pixmaps and destroy images */
|
|
if (pixmap_return && ximage) {
|
|
- xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
- XDestroyImage(ximage);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
+ if (ErrorStatus < 0) /* fatal error */
|
|
+ goto cleanup;
|
|
}
|
|
if (shapemask_return && shapeimage) {
|
|
- xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ }
|
|
+
|
|
+ cleanup:
|
|
+ if (ximage != NULL)
|
|
+ XDestroyImage(ximage);
|
|
+ if (shapeimage != NULL)
|
|
XDestroyImage(shapeimage);
|
|
+ if (ErrorStatus < 0) {
|
|
+ if (pixmap_return && *pixmap_return) {
|
|
+ XFreePixmap(display, *pixmap_return);
|
|
+ *pixmap_return = 0;
|
|
+ }
|
|
+ if (shapemask_return && *shapemask_return) {
|
|
+ XFreePixmap(display, *shapemask_return);
|
|
+ *shapemask_return = 0;
|
|
+ }
|
|
}
|
|
return (ErrorStatus);
|
|
}
|
|
diff --git a/src/XpmI.h b/src/XpmI.h
|
|
index ab7a680..6691693 100644
|
|
--- a/src/XpmI.h
|
|
+++ b/src/XpmI.h
|
|
@@ -195,7 +195,7 @@ FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image,
|
|
XpmInfo *info));
|
|
|
|
#if !defined(FOR_MSW) && !defined(AMIGA)
|
|
-FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d,
|
|
+FUNC(xpmCreatePixmapFromImage, int, (Display *display, Drawable d,
|
|
XImage *ximage, Pixmap *pixmap_return));
|
|
|
|
FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap,
|
|
diff --git a/src/create.c b/src/create.c
|
|
index 4921c7d..ec562b2 100644
|
|
--- a/src/create.c
|
|
+++ b/src/create.c
|
|
@@ -1652,7 +1652,7 @@ XpmCreatePixmapFromXpmImage(
|
|
Pixmap *shapemask_return,
|
|
XpmAttributes *attributes)
|
|
{
|
|
- XImage *ximage, *shapeimage;
|
|
+ XImage *ximage = NULL, *shapeimage = NULL;
|
|
int ErrorStatus;
|
|
|
|
/* initialize return values */
|
|
@@ -1668,16 +1668,34 @@ XpmCreatePixmapFromXpmImage(
|
|
&shapeimage : NULL),
|
|
attributes);
|
|
if (ErrorStatus < 0)
|
|
- return (ErrorStatus);
|
|
+ goto cleanup;
|
|
|
|
/* create the pixmaps and destroy images */
|
|
if (pixmap_return && ximage) {
|
|
- xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
- XDestroyImage(ximage);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
|
|
+ if (ErrorStatus < 0) /* fatal error */
|
|
+ goto cleanup;
|
|
}
|
|
if (shapemask_return && shapeimage) {
|
|
- xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ ErrorStatus =
|
|
+ xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
|
|
+ }
|
|
+
|
|
+ cleanup:
|
|
+ if (ximage != NULL)
|
|
+ XDestroyImage(ximage);
|
|
+ if (shapeimage != NULL)
|
|
XDestroyImage(shapeimage);
|
|
+ if (ErrorStatus < 0) {
|
|
+ if (pixmap_return && *pixmap_return) {
|
|
+ XFreePixmap(display, *pixmap_return);
|
|
+ *pixmap_return = 0;
|
|
+ }
|
|
+ if (shapemask_return && *shapemask_return) {
|
|
+ XFreePixmap(display, *shapemask_return);
|
|
+ *shapemask_return = 0;
|
|
+ }
|
|
}
|
|
return (ErrorStatus);
|
|
}
|
|
--
|
|
2.41.0
|
|
|