untrusted comment: verify with openbsd-72-base.pub RWQTKNnK3CZZ8IhQkFDVPrRg7ML5U8sxaCD1rObGnSaZIl40F8ZaYy6BjslyPCY4/rf4PXp1RW3qcqIEraLF66hJdNXtePErFAo= OpenBSD 7.2 errata 039, October 3, 2023: Fix several input validation errors in libX11 and libXpm. CVE-2023-43785 CVE-2023-43786 CVE-2023-43787 CVE-2023-43788 CVE-2023-43789 Apply by doing: signify -Vep /etc/signify/openbsd-72-base.pub -x 039_xlibs.patch.sig \ -m - | (cd /usr/xenocara && patch -p0) And then rebuild and install libX11 and libXpm: cd /usr/xenocara/lib/libX11 make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper build cd /usr/xenocara/lib/libXpm make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper build Index: lib/libX11/src/CrPixmap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/CrPixmap.c,v retrieving revision 1.2 diff -u -p -u -r1.2 CrPixmap.c --- lib/libX11/src/CrPixmap.c 18 May 2010 19:37:34 -0000 1.2 +++ lib/libX11/src/CrPixmap.c 23 Sep 2023 15:38:14 -0000 @@ -28,6 +28,7 @@ in this Software without prior written a #include #endif #include "Xlibint.h" +#include #ifdef USE_DYNAMIC_XCURSOR void @@ -46,6 +47,16 @@ Pixmap XCreatePixmap ( { Pixmap pid; register xCreatePixmapReq *req; + + /* + * Force a BadValue X Error if the requested dimensions are larger + * than the X11 protocol has room for, since that's how callers expect + * to get notified of errors. + */ + if (width > USHRT_MAX) + width = 0; + if (height > USHRT_MAX) + height = 0; LockDisplay(dpy); GetReq(CreatePixmap, req); Index: lib/libX11/src/ImUtil.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/ImUtil.c,v retrieving revision 1.13 diff -u -p -u -r1.13 ImUtil.c --- lib/libX11/src/ImUtil.c 28 Nov 2020 14:39:48 -0000 1.13 +++ lib/libX11/src/ImUtil.c 23 Sep 2023 15:38:14 -0000 @@ -30,6 +30,7 @@ in this Software without prior written a #include #include #include +#include #include "ImUtil.h" static int _XDestroyImage(XImage *); @@ -361,13 +362,22 @@ XImage *XCreateImage ( /* * compute per line accelerator. */ - { - if (format == ZPixmap) + if (format == ZPixmap) { + if ((INT_MAX / bits_per_pixel) < width) { + Xfree(image); + return NULL; + } + min_bytes_per_line = - ROUNDUP((bits_per_pixel * width), image->bitmap_pad); - else + ROUNDUP((bits_per_pixel * width), image->bitmap_pad); + } else { + if ((INT_MAX - offset) < width) { + Xfree(image); + return NULL; + } + min_bytes_per_line = - ROUNDUP((width + offset), image->bitmap_pad); + ROUNDUP((width + offset), image->bitmap_pad); } if (image_bytes_per_line == 0) { image->bytes_per_line = min_bytes_per_line; Index: lib/libX11/src/PutImage.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/PutImage.c,v retrieving revision 1.10 diff -u -p -u -r1.10 PutImage.c --- lib/libX11/src/PutImage.c 28 Nov 2020 14:39:48 -0000 1.10 +++ lib/libX11/src/PutImage.c 23 Sep 2023 15:38:14 -0000 @@ -30,6 +30,7 @@ in this Software without prior written a #include "Xlibint.h" #include "Xutil.h" #include +#include #include "Cr.h" #include "ImUtil.h" #include "reallocarray.h" @@ -914,8 +915,9 @@ PutSubImage ( req_width, req_height - SubImageHeight, dest_bits_per_pixel, dest_scanline_pad); } else { - int SubImageWidth = (((Available << 3) / dest_scanline_pad) - * dest_scanline_pad) - left_pad; + int SubImageWidth = ((((Available << 3) / dest_scanline_pad) + * dest_scanline_pad) - left_pad) + / dest_bits_per_pixel; PutSubImage(dpy, d, gc, image, req_xoffset, req_yoffset, x, y, (unsigned int) SubImageWidth, 1, @@ -961,6 +963,10 @@ XPutImage ( height = image->height - req_yoffset; if ((width <= 0) || (height <= 0)) return 0; + if (width > USHRT_MAX) + width = USHRT_MAX; + if (height > USHRT_MAX) + height = USHRT_MAX; if ((image->bits_per_pixel == 1) || (image->format != ZPixmap)) { dest_bits_per_pixel = 1; Index: lib/libX11/src/xkb/XKBGetMap.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libX11/src/xkb/XKBGetMap.c,v retrieving revision 1.8 diff -u -p -u -r1.8 XKBGetMap.c --- lib/libX11/src/xkb/XKBGetMap.c 4 Aug 2019 13:34:54 -0000 1.8 +++ lib/libX11/src/xkb/XKBGetMap.c 23 Sep 2023 15:38:14 -0000 @@ -182,7 +182,8 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, Xk if (offset + newMap->nSyms >= map->size_syms) { register int sz; - sz = map->size_syms + 128; + sz = offset + newMap->nSyms; + sz = ((sz + (unsigned) 128) / 128) * 128; _XkbResizeArray(map->syms, map->size_syms, sz, KeySym); if (map->syms == NULL) { map->size_syms = 0; @@ -191,8 +192,9 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, Xk map->size_syms = sz; } if (newMap->nSyms > 0) { - _XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], - newMap->nSyms); + if (_XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], + newMap->nSyms) == 0) + return BadLength; offset += newMap->nSyms; } else { @@ -222,8 +224,10 @@ _XkbReadKeySyms(XkbReadBufferPtr buf, Xk newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp); if (newSyms == NULL) return BadAlloc; - if (newMap->nSyms > 0) - _XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms); + if (newMap->nSyms > 0) { + if (_XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms) == 0) + return BadLength; + } else newSyms[0] = NoSymbol; oldMap->kt_index[0] = newMap->ktIndex[0]; Index: lib/libXpm/src/CrPFrBuf.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/CrPFrBuf.c,v retrieving revision 1.2 diff -u -p -u -r1.2 CrPFrBuf.c --- lib/libXpm/src/CrPFrBuf.c 31 Oct 2009 18:33:17 -0000 1.2 +++ lib/libXpm/src/CrPFrBuf.c 23 Sep 2023 15:38:14 -0000 @@ -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); } Index: lib/libXpm/src/CrPFrDat.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/CrPFrDat.c,v retrieving revision 1.2 diff -u -p -u -r1.2 CrPFrDat.c --- lib/libXpm/src/CrPFrDat.c 31 Oct 2009 18:33:17 -0000 1.2 +++ lib/libXpm/src/CrPFrDat.c 23 Sep 2023 15:38:14 -0000 @@ -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); } Index: lib/libXpm/src/CrPFrI.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/CrPFrI.c,v retrieving revision 1.2 diff -u -p -u -r1.2 CrPFrI.c --- lib/libXpm/src/CrPFrI.c 31 Oct 2009 18:33:17 -0000 1.2 +++ lib/libXpm/src/CrPFrI.c 23 Sep 2023 15:38:14 -0000 @@ -36,8 +36,9 @@ #include #endif #include "XpmI.h" +#include -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; } Index: lib/libXpm/src/RdFToP.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/RdFToP.c,v retrieving revision 1.3 diff -u -p -u -r1.3 RdFToP.c --- lib/libXpm/src/RdFToP.c 28 Sep 2013 17:40:35 -0000 1.3 +++ lib/libXpm/src/RdFToP.c 23 Sep 2023 15:38:14 -0000 @@ -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); } Index: lib/libXpm/src/XpmI.h =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/XpmI.h,v retrieving revision 1.4 diff -u -p -u -r1.4 XpmI.h --- lib/libXpm/src/XpmI.h 4 Jan 2020 18:00:46 -0000 1.4 +++ lib/libXpm/src/XpmI.h 23 Sep 2023 15:38:14 -0000 @@ -188,7 +188,7 @@ FUNC(xpmSetAttributes, void, (XpmAttribu 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, Index: lib/libXpm/src/create.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/create.c,v retrieving revision 1.5.24.1 diff -u -p -u -r1.5.24.1 create.c --- lib/libXpm/src/create.c 17 Jan 2023 16:31:20 -0000 1.5.24.1 +++ lib/libXpm/src/create.c 23 Sep 2023 15:38:14 -0000 @@ -997,6 +997,11 @@ CreateXImage( *image_return = NULL; return XpmNoMemory; } + if (width != 0 && (*image_return)->bits_per_pixel >= INT_MAX / width) { + XDestroyImage(*image_return); + *image_return = NULL; + return XpmNoMemory; + } /* now that bytes_per_line must have been set properly alloc data */ if((*image_return)->bytes_per_line == 0 || height == 0) return XpmNoMemory; @@ -1649,7 +1654,7 @@ XpmCreatePixmapFromXpmImage( Pixmap *shapemask_return, XpmAttributes *attributes) { - XImage *ximage, *shapeimage; + XImage *ximage = NULL, *shapeimage = NULL; int ErrorStatus; /* initialize return values */ @@ -1665,16 +1670,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); } Index: lib/libXpm/src/data.c =================================================================== RCS file: /cvs/OpenBSD/xenocara/lib/libXpm/src/data.c,v retrieving revision 1.4.42.1 diff -u -p -u -r1.4.42.1 data.c --- lib/libXpm/src/data.c 17 Jan 2023 16:31:20 -0000 1.4.42.1 +++ lib/libXpm/src/data.c 23 Sep 2023 15:38:14 -0000 @@ -108,7 +108,7 @@ ParseComment(xpmData *data) n++; s2++; } while (c == *s2 && *s2 != '\0' && c); - if (*s2 == '\0') { + if (*s2 == '\0' || c == '\0') { /* this is the end of the comment */ notend = 0; data->cptr--; @@ -259,13 +259,13 @@ xpmNextWord( int c; if (!data->type || data->type == XPMBUFFER) { - while (isspace(c = *data->cptr) && c != data->Eos) + while ((c = *data->cptr) && isspace(c) && (c != data->Eos)) data->cptr++; do { c = *data->cptr++; *buf++ = c; n++; - } while (!isspace(c) && c != data->Eos && n < buflen); + } while (c && !isspace(c) && (c != data->Eos) && (n < buflen)); n--; data->cptr--; } else {