diff options
author | Alex Richardson <arichardson@FreeBSD.org> | 2023-09-12 22:55:37 -0700 |
---|---|---|
committer | Alex Richardson <arichardson@FreeBSD.org> | 2023-09-12 23:18:50 -0700 |
commit | 01e754610df2195536c5b31c1e8df756480599d1 (patch) | |
tree | 84ce877cb7f5885384fdba2dd05a0008749c180f | |
parent | 07efd80468f6b595e6432edd28b8560ca7695ba0 (diff) |
While runnig some X11 applications on an Arm Morello platform I noticed
bus errors inside xrender. XRenderInfo uses a single malloc call to
allocate multiple objects in one single allocation and places those objects
directly after the XRenderInfo object. However, these calculations do not
ensure that this objects are sufficiently aligned. I noticed this because
on Morello (and other CHERI-enabled architectures) pointers need to be
strongly aligned. Instead of allocating a single block with potentially
misaligned subsequent objects, this change uses seprate allocations for
the four arrays.
This is an alternative to https://gitlab.freedesktop.org/xorg/lib/libxrender/-/merge_requests/12
Signed-off-by: Alex Richardson <arichardson@FreeBSD.org>
-rw-r--r-- | src/Xrender.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/src/Xrender.c b/src/Xrender.c index 61a1139..1755f41 100644 --- a/src/Xrender.c +++ b/src/Xrender.c @@ -294,11 +294,21 @@ XRenderFindDisplay (Display *dpy) return dpyinfo; } +static void +XRenderFreeXRenderInfo (XRenderInfo *xri) +{ + Xfree(xri->format); + Xfree(xri->screen); + Xfree(xri->depth); + Xfree(xri->visual); + Xfree(xri); +} + static int XRenderCloseDisplay (Display *dpy, XExtCodes *codes _X_UNUSED) { XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); - if (info && info->info) XFree (info->info); + if (info && info->info) XRenderFreeXRenderInfo (info->info); return XRenderExtRemoveDisplay (&XRenderExtensionInfo, dpy); } @@ -469,11 +479,8 @@ XRenderQueryFormats (Display *dpy) (rep.numVisuals < ((INT_MAX / 4) / sizeof (XRenderVisual))) && (rep.numSubpixel < ((INT_MAX / 4) / 4)) && (rep.length < (INT_MAX >> 2)) ) { - xri = Xmalloc (sizeof (XRenderInfo) + - (rep.numFormats * sizeof (XRenderPictFormat)) + - (rep.numScreens * sizeof (XRenderScreen)) + - (rep.numDepths * sizeof (XRenderDepth)) + - (rep.numVisuals * sizeof (XRenderVisual))); + /* Zero-initialize so that pointers are NULL if there is a failure. */ + xri = Xcalloc (1, sizeof (XRenderInfo)); rlength = ((rep.numFormats * sizeof (xPictFormInfo)) + (rep.numScreens * sizeof (xPictScreen)) + (rep.numDepths * sizeof (xPictDepth)) + @@ -498,13 +505,13 @@ XRenderQueryFormats (Display *dpy) } xri->major_version = async_state.major_version; xri->minor_version = async_state.minor_version; - xri->format = (XRenderPictFormat *) (xri + 1); + xri->format = Xcalloc(rep.numFormats, sizeof(XRenderPictFormat)); xri->nformat = (int) rep.numFormats; - xri->screen = (XRenderScreen *) (xri->format + rep.numFormats); + xri->screen = Xcalloc(rep.numScreens, sizeof(XRenderScreen)); xri->nscreen = (int) rep.numScreens; - xri->depth = (XRenderDepth *) (xri->screen + rep.numScreens); + xri->depth = Xcalloc(rep.numDepths, sizeof(XRenderDepth)); xri->ndepth = (int) rep.numDepths; - xri->visual = (XRenderVisual *) (xri->depth + rep.numDepths); + xri->visual = Xcalloc(rep.numVisuals, sizeof(XRenderVisual)); xri->nvisual = (int) rep.numVisuals; _XRead (dpy, (char *) xData, (long) rlength); format = xri->format; @@ -538,7 +545,7 @@ XRenderQueryFormats (Display *dpy) screen->subpixel = SubPixelUnknown; xPDepth = (xPictDepth *) (xScreen + 1); if (screen->ndepths > rep.numDepths) { - Xfree (xri); + XRenderFreeXRenderInfo(xri); Xfree (xData); _XEatDataWords (dpy, rep.length); UnlockDisplay (dpy); @@ -555,7 +562,7 @@ XRenderQueryFormats (Display *dpy) depth->visuals = visual; xVisual = (xPictVisual *) (xPDepth + 1); if (depth->nvisuals > rep.numVisuals) { - Xfree (xri); + XRenderFreeXRenderInfo (xri); Xfree (xData); _XEatDataWords (dpy, rep.length); UnlockDisplay (dpy); |