Version in base suite: 1.20.11-1+deb11u11 Base version: xorg-server_1.20.11-1+deb11u11 Target version: xorg-server_1.20.11-1+deb11u12 Base file: /srv/ftp-master.debian.org/ftp/pool/main/x/xorg-server/xorg-server_1.20.11-1+deb11u11.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/x/xorg-server/xorg-server_1.20.11-1+deb11u12.dsc debian/patches/20240403/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch | 61 +++ debian/patches/20240403/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch | 59 +++ debian/patches/20240403/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch | 73 ++++ debian/patches/20240403/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch | 166 ++++++++++ xorg-server-1.20.11/debian/changelog | 9 xorg-server-1.20.11/debian/patches/Xi-allocate-enough-XkbActions-for-our-buttons.patch | 17 - xorg-server-1.20.11/debian/patches/Xi-do-not-keep-linked-list-pointer-during-recursion.patch | 11 xorg-server-1.20.11/debian/patches/Xi-flush-hierarchy-events-after-adding-removing-mast.patch | 17 - xorg-server-1.20.11/debian/patches/Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch | 9 xorg-server-1.20.11/debian/patches/dix-Fix-use-after-free-in-input-device-shutdown.patch | 9 xorg-server-1.20.11/debian/patches/dix-when-disabling-a-master-float-disabled-slaved-de.patch | 17 - xorg-server-1.20.11/debian/patches/ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch | 15 xorg-server-1.20.11/debian/patches/glx-Call-XACE-hooks-on-the-GLX-buffer.patch | 9 xorg-server-1.20.11/debian/patches/series | 4 14 files changed, 402 insertions(+), 74 deletions(-) diff -u xorg-server-1.20.11/debian/changelog xorg-server-1.20.11/debian/changelog --- xorg-server-1.20.11/debian/changelog +++ xorg-server-1.20.11/debian/changelog @@ -1,3 +1,12 @@ +xorg-server (2:1.20.11-1+deb11u12) bullseye-security; urgency=high + + * CVE-2024-31080: Heap buffer overread/data leakage in ProcXIGetSelectedEvents + * CVE-2024-31081: Heap buffer overread/data leakage in ProcXIPassiveGrabDevice + * CVE-2024-31082: Heap buffer overread/data leakage in ProcAppleDRICreatePixmap + * CVE-2024-31083: User-after-free in ProcRenderAddGlyphs + + -- Julien Cristau Thu, 04 Apr 2024 15:13:36 +0200 + xorg-server (2:1.20.11-1+deb11u11) bullseye-security; urgency=high * Non-maintainer upload by the Security Team. diff -u xorg-server-1.20.11/debian/patches/Xi-allocate-enough-XkbActions-for-our-buttons.patch xorg-server-1.20.11/debian/patches/Xi-allocate-enough-XkbActions-for-our-buttons.patch --- xorg-server-1.20.11/debian/patches/Xi-allocate-enough-XkbActions-for-our-buttons.patch +++ xorg-server-1.20.11/debian/patches/Xi-allocate-enough-XkbActions-for-our-buttons.patch @@ -14,15 +14,13 @@ This vulnerability was discovered by: Jan-Niklas Sohn working with Trend Micro Zero Day Initiative --- - Xi/exevents.c | 12 ++++++------ - dix/devices.c | 10 ++++++++++ + Xi/exevents.c | 12 ++++++------ + dix/devices.c | 10 ++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) -diff --git a/Xi/exevents.c b/Xi/exevents.c -index dcd4efb3bc7a..54ea11a93872 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c -@@ -611,13 +611,13 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) +@@ -567,13 +567,13 @@ DeepCopyPointerClasses(DeviceIntPtr from } if (from->button->xkb_acts) { @@ -42,11 +40,9 @@ } else { free(to->button->xkb_acts); -diff --git a/dix/devices.c b/dix/devices.c -index b063128df072..3f3224d6264f 100644 --- a/dix/devices.c +++ b/dix/devices.c -@@ -2539,6 +2539,8 @@ RecalculateMasterButtons(DeviceIntPtr slave) +@@ -2499,6 +2499,8 @@ RecalculateMasterButtons(DeviceIntPtr sl if (master->button && master->button->numButtons != maxbuttons) { int i; @@ -55,7 +51,7 @@ DeviceChangedEvent event = { .header = ET_Internal, .type = ET_DeviceChanged, -@@ -2549,6 +2551,14 @@ RecalculateMasterButtons(DeviceIntPtr slave) +@@ -2509,6 +2511,14 @@ RecalculateMasterButtons(DeviceIntPtr sl }; master->button->numButtons = maxbuttons; @@ -70,6 +66,3 @@ memcpy(&event.buttons.names, master->button->labels, maxbuttons * sizeof(Atom)); --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/Xi-do-not-keep-linked-list-pointer-during-recursion.patch xorg-server-1.20.11/debian/patches/Xi-do-not-keep-linked-list-pointer-during-recursion.patch --- xorg-server-1.20.11/debian/patches/Xi-do-not-keep-linked-list-pointer-during-recursion.patch +++ xorg-server-1.20.11/debian/patches/Xi-do-not-keep-linked-list-pointer-during-recursion.patch @@ -24,14 +24,12 @@ This vulnerability was discovered by: Jan-Niklas Sohn working with Trend Micro Zero Day Initiative --- - dix/devices.c | 15 ++++++++++++--- + dix/devices.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) -diff --git a/dix/devices.c b/dix/devices.c -index 3f3224d62..3a64d8702 100644 --- a/dix/devices.c +++ b/dix/devices.c -@@ -451,14 +451,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) +@@ -451,14 +451,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sen { DeviceIntPtr *prev, other; BOOL enabled; @@ -55,7 +53,7 @@ return FALSE; TouchEndPhysicallyActiveTouches(dev); -@@ -509,6 +515,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) +@@ -508,6 +514,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sen LeaveWindow(dev); SetFocusOut(dev); @@ -65,6 +63,3 @@ *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/Xi-flush-hierarchy-events-after-adding-removing-mast.patch xorg-server-1.20.11/debian/patches/Xi-flush-hierarchy-events-after-adding-removing-mast.patch --- xorg-server-1.20.11/debian/patches/Xi-flush-hierarchy-events-after-adding-removing-mast.patch +++ xorg-server-1.20.11/debian/patches/Xi-flush-hierarchy-events-after-adding-removing-mast.patch @@ -24,14 +24,12 @@ This vulnerability was discovered by: Jan-Niklas Sohn working with Trend Micro Zero Day Initiative --- - Xi/xichangehierarchy.c | 30 ++++++++++++++++++++++++------ - 1 file changed, 24 insertions(+), 6 deletions(-) + Xi/xichangehierarchy.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) -diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c -index 01eb7a8af4..67eedddec6 100644 --- a/Xi/xichangehierarchy.c +++ b/Xi/xichangehierarchy.c -@@ -340,6 +340,11 @@ ProcXIChangeHierarchy(ClientPtr client) +@@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client) size_t len; /* length of data remaining in request */ int rc = Success; int flags[MAXDEVICES] = { 0 }; @@ -43,7 +41,7 @@ REQUEST(xXIChangeHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq); -@@ -389,8 +394,9 @@ ProcXIChangeHierarchy(ClientPtr client) +@@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = add_master(client, c, flags); if (rc != Success) goto unwind; @@ -54,7 +52,7 @@ case XIRemoveMaster: { xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any; -@@ -399,8 +405,9 @@ ProcXIChangeHierarchy(ClientPtr client) +@@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = remove_master(client, r, flags); if (rc != Success) goto unwind; @@ -65,7 +63,7 @@ case XIDetachSlave: { xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any; -@@ -409,8 +416,9 @@ ProcXIChangeHierarchy(ClientPtr client) +@@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client) rc = detach_slave(client, c, flags); if (rc != Success) goto unwind; @@ -104,6 +102,3 @@ + XISendDeviceHierarchyEvent(flags); return rc; } --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch xorg-server-1.20.11/debian/patches/Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch --- xorg-server-1.20.11/debian/patches/Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch +++ xorg-server-1.20.11/debian/patches/Xi-when-creating-a-new-ButtonClass-set-the-number-of.patch @@ -17,14 +17,12 @@ This vulnerability was discovered by: Jan-Niklas Sohn working with Trend Micro Zero Day Initiative --- - Xi/exevents.c | 1 + + Xi/exevents.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/Xi/exevents.c b/Xi/exevents.c -index 54ea11a938..e161714682 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c -@@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) +@@ -561,6 +561,7 @@ DeepCopyPointerClasses(DeviceIntPtr from to->button = calloc(1, sizeof(ButtonClassRec)); if (!to->button) FatalError("[Xi] no memory for class shift.\n"); @@ -32,6 +30,3 @@ } else classes->button = NULL; --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/dix-Fix-use-after-free-in-input-device-shutdown.patch xorg-server-1.20.11/debian/patches/dix-Fix-use-after-free-in-input-device-shutdown.patch --- xorg-server-1.20.11/debian/patches/dix-Fix-use-after-free-in-input-device-shutdown.patch +++ xorg-server-1.20.11/debian/patches/dix-Fix-use-after-free-in-input-device-shutdown.patch @@ -57,14 +57,12 @@ Signed-off-by: Povilas Kanapickas --- - dix/devices.c | 1 + + dix/devices.c | 1 + 1 file changed, 1 insertion(+) -diff --git a/dix/devices.c b/dix/devices.c -index e62c34c55e95..5f9ce1678fc4 100644 --- a/dix/devices.c +++ b/dix/devices.c -@@ -520,6 +520,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) +@@ -539,6 +539,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sen } RecalculateMasterButtons(dev); @@ -72,6 +70,3 @@ return TRUE; } --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/dix-when-disabling-a-master-float-disabled-slaved-de.patch xorg-server-1.20.11/debian/patches/dix-when-disabling-a-master-float-disabled-slaved-de.patch --- xorg-server-1.20.11/debian/patches/dix-when-disabling-a-master-float-disabled-slaved-de.patch +++ xorg-server-1.20.11/debian/patches/dix-when-disabling-a-master-float-disabled-slaved-de.patch @@ -15,14 +15,12 @@ Related to CVE-2024-21886, ZDI-CAN-22840 --- - dix/devices.c | 12 ++++++++++++ + dix/devices.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) -diff --git a/dix/devices.c b/dix/devices.c -index c7fa8fad69..87f4d4a213 100644 --- a/dix/devices.c +++ b/dix/devices.c -@@ -482,6 +482,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) +@@ -480,6 +480,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sen flags[other->id] |= XISlaveDetached; } } @@ -36,18 +34,15 @@ } else { for (other = inputInfo.devices; other; other = other->next) { -@@ -1088,6 +1095,11 @@ CloseDownDevices(void) +@@ -1075,6 +1082,11 @@ CloseDownDevices(void) + if (!IsMaster(dev) && !IsFloating(dev)) dev->master = NULL; } - ++ + for (dev = inputInfo.off_devices; dev; dev = dev->next) { + if (!IsMaster(dev) && !IsFloating(dev)) + dev->master = NULL; + } -+ + CloseDeviceList(&inputInfo.devices); CloseDeviceList(&inputInfo.off_devices); - --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch xorg-server-1.20.11/debian/patches/ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch --- xorg-server-1.20.11/debian/patches/ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch +++ xorg-server-1.20.11/debian/patches/ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch @@ -19,15 +19,13 @@ Signed-off-by: Olivier Fourdan Acked-by: Peter Hutterer --- - hw/kdrive/ephyr/ephyrcursor.c | 2 +- - hw/xwayland/xwayland-cursor.c | 2 +- + hw/kdrive/ephyr/ephyrcursor.c | 2 +- + hw/xwayland/xwayland-cursor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -diff --git a/hw/kdrive/ephyr/ephyrcursor.c b/hw/kdrive/ephyr/ephyrcursor.c -index f991899c5..3f192d034 100644 --- a/hw/kdrive/ephyr/ephyrcursor.c +++ b/hw/kdrive/ephyr/ephyrcursor.c -@@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { +@@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSprit Bool ephyrCursorInit(ScreenPtr screen) { @@ -36,11 +34,9 @@ sizeof(ephyrCursorRec))) return FALSE; -diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c -index e3c1aaa50..bd94b0cfb 100644 --- a/hw/xwayland/xwayland-cursor.c +++ b/hw/xwayland/xwayland-cursor.c -@@ -431,7 +431,7 @@ static miPointerScreenFuncRec xwl_pointer_screen_funcs = { +@@ -305,7 +305,7 @@ static miPointerScreenFuncRec xwl_pointe Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen) { @@ -49,6 +45,3 @@ return FALSE; return miPointerInitialize(xwl_screen->screen, --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/glx-Call-XACE-hooks-on-the-GLX-buffer.patch xorg-server-1.20.11/debian/patches/glx-Call-XACE-hooks-on-the-GLX-buffer.patch --- xorg-server-1.20.11/debian/patches/glx-Call-XACE-hooks-on-the-GLX-buffer.patch +++ xorg-server-1.20.11/debian/patches/glx-Call-XACE-hooks-on-the-GLX-buffer.patch @@ -23,11 +23,9 @@ Signed-off-by: Olivier Fourdan --- - glx/glxcmds.c | 8 ++++++++ + glx/glxcmds.c | 8 ++++++++ 1 file changed, 8 insertions(+) -diff --git a/glx/glxcmds.c b/glx/glxcmds.c -index fc26a2e34..1e46d0c72 100644 --- a/glx/glxcmds.c +++ b/glx/glxcmds.c @@ -48,6 +48,7 @@ @@ -38,7 +36,7 @@ static char GLXServerVendorName[] = "SGI"; -@@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, +@@ -1371,6 +1372,13 @@ DoCreatePbuffer(ClientPtr client, int sc if (!pPixmap) return BadAlloc; @@ -52,6 +50,3 @@ /* Assign the pixmap the same id as the pbuffer and add it as a * resource so it and the DRI2 drawable will be reclaimed when the * pbuffer is destroyed. */ --- -2.43.0 - diff -u xorg-server-1.20.11/debian/patches/series xorg-server-1.20.11/debian/patches/series --- xorg-server-1.20.11/debian/patches/series +++ xorg-server-1.20.11/debian/patches/series @@ -36,3 +36,7 @@ ephyr-xwayland-Use-the-proper-private-key-for-cursor.patch glx-Call-XACE-hooks-on-the-GLX-buffer.patch dix-Fix-use-after-free-in-input-device-shutdown.patch +20240403/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch +20240403/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch +20240403/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch +20240403/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch only in patch2: unchanged: --- xorg-server-1.20.11.orig/debian/patches/20240403/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch +++ xorg-server-1.20.11/debian/patches/20240403/0001-Xi-ProcXIGetSelectedEvents-needs-to-use-unswapped-le.patch @@ -0,0 +1,61 @@ +From 8a7cd0e3ef194610300c1a38fb5a5423b23dd6a5 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:51:45 -0700 +Subject: [PATCH 1/4] Xi: ProcXIGetSelectedEvents needs to use unswapped length + to send reply + +CVE-2024-31080 + +Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762 +Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.") +Signed-off-by: Alan Coopersmith +Part-of: +(cherry picked from commit 96798fc1967491c80a4d0c8d9e0a80586cb2152b) +--- + Xi/xiselectev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/Xi/xiselectev.c ++++ b/Xi/xiselectev.c +@@ -292,16 +292,17 @@ ProcXIGetSelectedEvents(ClientPtr client + int rc, i; + WindowPtr win; + char *buffer = NULL; + xXIGetSelectedEventsReply reply; + OtherInputMasks *masks; + InputClientsPtr others = NULL; + xXIEventMask *evmask = NULL; + DeviceIntPtr dev; ++ uint32_t length; + + REQUEST(xXIGetSelectedEventsReq); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); + + rc = dixLookupWindow(&win, stuff->win, client, DixGetAttrAccess); + if (rc != Success) + return rc; + +@@ -361,20 +362,22 @@ ProcXIGetSelectedEvents(ClientPtr client + memcpy(&evmask[1], devmask, j + 1); + evmask = (xXIEventMask *) ((char *) evmask + + sizeof(xXIEventMask) + mask_len * 4); + break; + } + } + } + ++ /* save the value before SRepXIGetSelectedEvents swaps it */ ++ length = reply.length; + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + + if (reply.num_masks) +- WriteToClient(client, reply.length * 4, buffer); ++ WriteToClient(client, length * 4, buffer); + + free(buffer); + return Success; + } + + void + SRepXIGetSelectedEvents(ClientPtr client, + int len, xXIGetSelectedEventsReply * rep) only in patch2: unchanged: --- xorg-server-1.20.11.orig/debian/patches/20240403/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch +++ xorg-server-1.20.11/debian/patches/20240403/0002-Xi-ProcXIPassiveGrabDevice-needs-to-use-unswapped-le.patch @@ -0,0 +1,59 @@ +From cea92ca78f900bfb4c9a5540dfd631e065b9151b Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 18:56:27 -0700 +Subject: [PATCH 2/4] Xi: ProcXIPassiveGrabDevice needs to use unswapped length + to send reply + +CVE-2024-31081 + +Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.") +Signed-off-by: Alan Coopersmith +Part-of: +(cherry picked from commit 3e77295f888c67fc7645db5d0c00926a29ffecee) +--- + Xi/xipassivegrab.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -88,16 +88,17 @@ ProcXIPassiveGrabDevice(ClientPtr client + }; + int i, ret = Success; + uint32_t *modifiers; + xXIGrabModifierInfo *modifiers_failed = NULL; + GrabMask mask = { 0 }; + GrabParameters param; + void *tmp; + int mask_len; ++ uint32_t length; + + REQUEST(xXIPassiveGrabDeviceReq); + REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, + ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; + else if (stuff->deviceid == XIAllMasterDevices) +@@ -229,19 +230,21 @@ ProcXIPassiveGrabDevice(ClientPtr client + if (client->swapped) + swapl(&info->modifiers); + + rep.num_modifiers++; + rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo)); + } + } + ++ /* save the value before SRepXIPassiveGrabDevice swaps it */ ++ length = rep.length; + WriteReplyToClient(client, sizeof(rep), &rep); + if (rep.num_modifiers) +- WriteToClient(client, rep.length * 4, modifiers_failed); ++ WriteToClient(client, length * 4, modifiers_failed); + + out: + free(modifiers_failed); + xi2mask_free(&mask.xi2mask); + return ret; + } + + void _X_COLD only in patch2: unchanged: --- xorg-server-1.20.11.orig/debian/patches/20240403/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch +++ xorg-server-1.20.11/debian/patches/20240403/0003-Xquartz-ProcAppleDRICreatePixmap-needs-to-use-unswap.patch @@ -0,0 +1,73 @@ +From 0e34d8ebc98a0ba6f9f0a2f8f5045761bccc45d3 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 22 Mar 2024 19:07:34 -0700 +Subject: [PATCH 3/4] Xquartz: ProcAppleDRICreatePixmap needs to use unswapped + length to send reply + +CVE-2024-31082 + +Fixes: 14205ade0 ("XQuartz: appledri: Fix byte swapping in replies") +Signed-off-by: Alan Coopersmith +Part-of: +(cherry picked from commit 6c684d035c06fd41c727f0ef0744517580864cef) +--- + hw/xquartz/xpr/appledri.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/xquartz/xpr/appledri.c b/hw/xquartz/xpr/appledri.c +index 77574655b..40422b61a 100644 +--- a/hw/xquartz/xpr/appledri.c ++++ b/hw/xquartz/xpr/appledri.c +@@ -267,16 +267,17 @@ ProcAppleDRICreatePixmap(ClientPtr client) + { + REQUEST(xAppleDRICreatePixmapReq); + DrawablePtr pDrawable; + int rc; + char path[PATH_MAX]; + xAppleDRICreatePixmapReply rep; + int width, height, pitch, bpp; + void *ptr; ++ CARD32 stringLength; + + REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + + if (rc != Success) + return rc; +@@ -302,29 +303,30 @@ ProcAppleDRICreatePixmap(ClientPtr client) + rep.height = height; + rep.pitch = pitch; + rep.bpp = bpp; + rep.size = pitch * height; + + if (sizeof(rep) != sz_xAppleDRICreatePixmapReply) + ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); + ++ stringLength = rep.stringLength; /* save unswapped value */ + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swapl(&rep.stringLength); + swapl(&rep.width); + swapl(&rep.height); + swapl(&rep.pitch); + swapl(&rep.bpp); + swapl(&rep.size); + } + + WriteToClient(client, sizeof(rep), &rep); +- WriteToClient(client, rep.stringLength, path); ++ WriteToClient(client, stringLength, path); + + return Success; + } + + static int + ProcAppleDRIDestroyPixmap(ClientPtr client) + { + DrawablePtr pDrawable; +-- +2.43.0 + only in patch2: unchanged: --- xorg-server-1.20.11.orig/debian/patches/20240403/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch +++ xorg-server-1.20.11/debian/patches/20240403/0004-render-fix-refcounting-of-glyphs-during-ProcRenderAd.patch @@ -0,0 +1,166 @@ +From 1173156404be826f50f453ca11bda28ccb5a5268 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Tue, 30 Jan 2024 13:13:35 +1000 +Subject: [PATCH 4/4] render: fix refcounting of glyphs during + ProcRenderAddGlyphs + +Previously, AllocateGlyph would return a new glyph with refcount=0 and a +re-used glyph would end up not changing the refcount at all. The +resulting glyph_new array would thus have multiple entries pointing to +the same non-refcounted glyphs. + +AddGlyph may free a glyph, resulting in a UAF when the same glyph +pointer is then later used. + +Fix this by returning a refcount of 1 for a new glyph and always +incrementing the refcount for a re-used glyph, followed by dropping that +refcount back down again when we're done with it. + +CVE-2024-31083, ZDI-CAN-22880 + +This vulnerability was discovered by: +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative + +Part-of: +(cherry picked from commit bdca6c3d1f5057eeb31609b1280fc93237b00c77) +--- + render/glyph.c | 5 +++-- + render/glyphstr.h | 2 ++ + render/render.c | 15 +++++++++++---- + 3 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/render/glyph.c b/render/glyph.c +index f3ed9cf4c..d5fc5f3c9 100644 +--- a/render/glyph.c ++++ b/render/glyph.c +@@ -240,20 +240,21 @@ FreeGlyphPicture(GlyphPtr glyph) + FreePicture((void *) GetGlyphPicture(glyph, pScreen), 0); + + ps = GetPictureScreenIfSet(pScreen); + if (ps) + (*ps->UnrealizeGlyph) (pScreen, glyph); + } + } + +-static void ++void + FreeGlyph(GlyphPtr glyph, int format) + { + CheckDuplicates(&globalGlyphs[format], "FreeGlyph"); ++ BUG_RETURN(glyph->refcnt == 0); + if (--glyph->refcnt == 0) { + GlyphRefPtr gr; + int i; + int first; + CARD32 signature; + + first = -1; + for (i = 0; i < globalGlyphs[format].hashSet->size; i++) +@@ -349,17 +350,17 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth) + int i; + int head_size; + + head_size = sizeof(GlyphRec) + screenInfo.numScreens * sizeof(PicturePtr); + size = (head_size + dixPrivatesSize(PRIVATE_GLYPH)); + glyph = (GlyphPtr) malloc(size); + if (!glyph) + return 0; +- glyph->refcnt = 0; ++ glyph->refcnt = 1; + glyph->size = size + sizeof(xGlyphInfo); + glyph->info = *gi; + dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH); + + for (i = 0; i < screenInfo.numScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + SetGlyphPicture(glyph, pScreen, NULL); + ps = GetPictureScreenIfSet(pScreen); +diff --git a/render/glyphstr.h b/render/glyphstr.h +index 2f51bd244..e8034556d 100644 +--- a/render/glyphstr.h ++++ b/render/glyphstr.h +@@ -104,16 +104,18 @@ extern void + + extern Bool + DeleteGlyph(GlyphSetPtr glyphSet, Glyph id); + + extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id); + + extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format); + ++extern void FreeGlyph(GlyphPtr glyph, int format); ++ + extern Bool + ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change); + + extern GlyphSetPtr AllocateGlyphSet(int fdepth, PictFormatPtr format); + + extern int + FreeGlyphSet(void *value, XID gid); + +diff --git a/render/render.c b/render/render.c +index 456f156d4..5bc2a204b 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1071,16 +1071,17 @@ ProcRenderAddGlyphs(ClientPtr client) + err = HashGlyph(&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash(glyph_new->sha1, glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) { + glyph_new->found = TRUE; ++ ++glyph_new->glyph->refcnt; + } + else { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph(&gi[i], glyphSet->fdepth); + if (!glyph) { + err = BadAlloc; +@@ -1163,30 +1164,36 @@ ProcRenderAddGlyphs(ClientPtr client) + if (remain || i < nglyphs) { + err = BadLength; + goto bail; + } + if (!ResizeGlyphSet(glyphSet, nglyphs)) { + err = BadAlloc; + goto bail; + } +- for (i = 0; i < nglyphs; i++) ++ for (i = 0; i < nglyphs; i++) { + AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id); ++ FreeGlyph(glyphs[i].glyph, glyphSet->fdepth); ++ } + + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return Success; + bail: + if (pSrc) + FreePicture((void *) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader(pSrcPix); +- for (i = 0; i < nglyphs; i++) +- if (glyphs[i].glyph && !glyphs[i].found) +- free(glyphs[i].glyph); ++ for (i = 0; i < nglyphs; i++) { ++ if (glyphs[i].glyph) { ++ --glyphs[i].glyph->refcnt; ++ if (!glyphs[i].found) ++ free(glyphs[i].glyph); ++ } ++ } + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return err; + } + + static int + ProcRenderAddGlyphsFromPicture(ClientPtr client) + { +-- +2.43.0 +