wok-current rev 25640

Patch xorg-server (CVE-2023-6816, CVE-2024-0229, CVE-2024-0408, CVE-2024-0409, CVE-2024-21885, CVE-2024-21886)
author Stanislas Leduc <shann@slitaz.org>
date Tue Jan 16 20:32:03 2024 +0000 (5 months ago)
parents 7e95bf4819fa
children 960bef77d367
files xorg-server/receipt xorg-server/stuff/CVE-2023-6816.patch xorg-server/stuff/CVE-2024-0229-1.patch xorg-server/stuff/CVE-2024-0229-2.patch xorg-server/stuff/CVE-2024-0229-3.patch xorg-server/stuff/CVE-2024-0408.patch xorg-server/stuff/CVE-2024-0409.patch xorg-server/stuff/CVE-2024-21885.patch xorg-server/stuff/CVE-2024-21886-1.patch xorg-server/stuff/CVE-2024-21886-2.patch
line diff
     1.1 --- a/xorg-server/receipt	Tue Jan 16 18:22:10 2024 +0000
     1.2 +++ b/xorg-server/receipt	Tue Jan 16 20:32:03 2024 +0000
     1.3 @@ -64,6 +64,18 @@
     1.4  	patch -p1 < $stuff/CVE-2023-6377.patch
     1.5  	patch -p1 < $stuff/CVE-2023-6478.patch
     1.6  
     1.7 +	# Patch xorg CVEs January 2024
     1.8 +	# see https://lists.x.org/archives/xorg/2024-January/061525.html
     1.9 +	patch -p1 < $stuff/CVE-2023-6816.patch
    1.10 +	patch -p1 < $stuff/CVE-2024-0229-1.patch
    1.11 +	patch -p1 < $stuff/CVE-2024-0229-2.patch
    1.12 +	patch -p1 < $stuff/CVE-2024-0229-3.patch
    1.13 +	patch -p1 < $stuff/CVE-2024-0408.patch
    1.14 +	patch -p1 < $stuff/CVE-2024-0409.patch
    1.15 +	patch -p1 < $stuff/CVE-2024-21885.patch
    1.16 +	patch -p1 < $stuff/CVE-2024-21886-1.patch
    1.17 +	patch -p1 < $stuff/CVE-2024-21886-2.patch
    1.18 +
    1.19  	# Xephyr make possible to use Xorg in a chroot.
    1.20  	./configure \
    1.21  		--prefix=/usr \
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xorg-server/stuff/CVE-2023-6816.patch	Tue Jan 16 20:32:03 2024 +0000
     2.3 @@ -0,0 +1,51 @@
     2.4 +From 9e2ecb2af8302dedc49cb6a63ebe063c58a9e7e3 Mon Sep 17 00:00:00 2001
     2.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
     2.6 +Date: Thu, 14 Dec 2023 11:29:49 +1000
     2.7 +Subject: [PATCH] dix: allocate enough space for logical button maps
     2.8 +
     2.9 +Both DeviceFocusEvent and the XIQueryPointer reply contain a bit for
    2.10 +each logical button currently down. Since buttons can be arbitrarily mapped
    2.11 +to anything up to 255 make sure we have enough bits for the maximum mapping.
    2.12 +
    2.13 +CVE-2023-6816, ZDI-CAN-22664, ZDI-CAN-22665
    2.14 +
    2.15 +This vulnerability was discovered by:
    2.16 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    2.17 +---
    2.18 + Xi/xiquerypointer.c | 3 +--
    2.19 + dix/enterleave.c    | 5 +++--
    2.20 + 2 files changed, 4 insertions(+), 4 deletions(-)
    2.21 +
    2.22 +diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
    2.23 +index 5b77b1a444..2b05ac5f39 100644
    2.24 +--- a/Xi/xiquerypointer.c
    2.25 ++++ b/Xi/xiquerypointer.c
    2.26 +@@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client)
    2.27 +     if (pDev->button) {
    2.28 +         int i;
    2.29 + 
    2.30 +-        rep.buttons_len =
    2.31 +-            bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
    2.32 ++        rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */
    2.33 +         rep.length += rep.buttons_len;
    2.34 +         buttons = calloc(rep.buttons_len, 4);
    2.35 +         if (!buttons)
    2.36 +diff --git a/dix/enterleave.c b/dix/enterleave.c
    2.37 +index 867ec74363..ded8679d76 100644
    2.38 +--- a/dix/enterleave.c
    2.39 ++++ b/dix/enterleave.c
    2.40 +@@ -784,8 +784,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
    2.41 + 
    2.42 +     mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
    2.43 + 
    2.44 +-    /* XI 2 event */
    2.45 +-    btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
    2.46 ++    /* XI 2 event contains the logical button map - maps are CARD8
    2.47 ++     * so we need 256 bits for the possibly maximum mapping */
    2.48 ++    btlen = (mouse->button) ? bits_to_bytes(256) : 0;
    2.49 +     btlen = bytes_to_int32(btlen);
    2.50 +     len = sizeof(xXIFocusInEvent) + btlen * 4;
    2.51 + 
    2.52 +-- 
    2.53 +GitLab
    2.54 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xorg-server/stuff/CVE-2024-0229-1.patch	Tue Jan 16 20:32:03 2024 +0000
     3.3 @@ -0,0 +1,83 @@
     3.4 +From ece23be888a93b741aa1209d1dbf64636109d6a5 Mon Sep 17 00:00:00 2001
     3.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
     3.6 +Date: Mon, 18 Dec 2023 14:27:50 +1000
     3.7 +Subject: [PATCH] dix: Allocate sufficient xEvents for our DeviceStateNotify
     3.8 +
     3.9 +If a device has both a button class and a key class and numButtons is
    3.10 +zero, we can get an OOB write due to event under-allocation.
    3.11 +
    3.12 +This function seems to assume a device has either keys or buttons, not
    3.13 +both. It has two virtually identical code paths, both of which assume
    3.14 +they're applying to the first event in the sequence.
    3.15 +
    3.16 +A device with both a key and button class triggered a logic bug - only
    3.17 +one xEvent was allocated but the deviceStateNotify pointer was pushed on
    3.18 +once per type. So effectively this logic code:
    3.19 +
    3.20 +   int count = 1;
    3.21 +   if (button && nbuttons > 32) count++;
    3.22 +   if (key && nbuttons > 0) count++;
    3.23 +   if (key && nkeys > 32) count++; // this is basically always true
    3.24 +   // count is at 2 for our keys + zero button device
    3.25 +
    3.26 +   ev = alloc(count * sizeof(xEvent));
    3.27 +   FixDeviceStateNotify(ev);
    3.28 +   if (button)
    3.29 +     FixDeviceStateNotify(ev++);
    3.30 +   if (key)
    3.31 +     FixDeviceStateNotify(ev++);   // santa drops into the wrong chimney here
    3.32 +
    3.33 +If the device has more than 3 valuators, the OOB is pushed back - we're
    3.34 +off by one so it will happen when the last deviceValuator event is
    3.35 +written instead.
    3.36 +
    3.37 +Fix this by allocating the maximum number of events we may allocate.
    3.38 +Note that the current behavior is not protocol-correct anyway, this
    3.39 +patch fixes only the allocation issue.
    3.40 +
    3.41 +Note that this issue does not trigger if the device has at least one
    3.42 +button. While the server does not prevent a button class with zero
    3.43 +buttons, it is very unlikely.
    3.44 +
    3.45 +CVE-2024-0229, ZDI-CAN-22678
    3.46 +
    3.47 +This vulnerability was discovered by:
    3.48 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    3.49 +---
    3.50 + dix/enterleave.c | 6 +++---
    3.51 + 1 file changed, 3 insertions(+), 3 deletions(-)
    3.52 +
    3.53 +diff --git a/dix/enterleave.c b/dix/enterleave.c
    3.54 +index ded8679d76..17964b00a4 100644
    3.55 +--- a/dix/enterleave.c
    3.56 ++++ b/dix/enterleave.c
    3.57 +@@ -675,7 +675,8 @@ static void
    3.58 + DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
    3.59 + {
    3.60 +     int evcount = 1;
    3.61 +-    deviceStateNotify *ev, *sev;
    3.62 ++    deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
    3.63 ++    deviceStateNotify *ev;
    3.64 +     deviceKeyStateNotify *kev;
    3.65 +     deviceButtonStateNotify *bev;
    3.66 + 
    3.67 +@@ -714,7 +715,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
    3.68 +         }
    3.69 +     }
    3.70 + 
    3.71 +-    sev = ev = xallocarray(evcount, sizeof(xEvent));
    3.72 ++    ev = sev;
    3.73 +     FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
    3.74 + 
    3.75 +     if (b != NULL) {
    3.76 +@@ -770,7 +771,6 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
    3.77 + 
    3.78 +     DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
    3.79 +                           DeviceStateNotifyMask, NullGrab);
    3.80 +-    free(sev);
    3.81 + }
    3.82 + 
    3.83 + void
    3.84 +-- 
    3.85 +GitLab
    3.86 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xorg-server/stuff/CVE-2024-0229-2.patch	Tue Jan 16 20:32:03 2024 +0000
     4.3 @@ -0,0 +1,217 @@
     4.4 +From 219c54b8a3337456ce5270ded6a67bcde53553d5 Mon Sep 17 00:00:00 2001
     4.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
     4.6 +Date: Mon, 18 Dec 2023 12:26:20 +1000
     4.7 +Subject: [PATCH] dix: fix DeviceStateNotify event calculation
     4.8 +
     4.9 +The previous code only made sense if one considers buttons and keys to
    4.10 +be mutually exclusive on a device. That is not necessarily true, causing
    4.11 +a number of issues.
    4.12 +
    4.13 +This function allocates and fills in the number of xEvents we need to
    4.14 +send the device state down the wire.  This is split across multiple
    4.15 +32-byte devices including one deviceStateNotify event and optional
    4.16 +deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple)
    4.17 +deviceValuator events.
    4.18 +
    4.19 +The previous behavior would instead compose a sequence
    4.20 +of [state, buttonstate, state, keystate, valuator...]. This is not
    4.21 +protocol correct, and on top of that made the code extremely convoluted.
    4.22 +
    4.23 +Fix this by streamlining: add both button and key into the deviceStateNotify
    4.24 +and then append the key state and button state, followed by the
    4.25 +valuators. Finally, the deviceValuator events contain up to 6 valuators
    4.26 +per event but we only ever sent through 3 at a time. Let's double that
    4.27 +troughput.
    4.28 +
    4.29 +CVE-2024-0229, ZDI-CAN-22678
    4.30 +
    4.31 +This vulnerability was discovered by:
    4.32 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    4.33 +---
    4.34 + dix/enterleave.c | 121 ++++++++++++++++++++---------------------------
    4.35 + 1 file changed, 52 insertions(+), 69 deletions(-)
    4.36 +
    4.37 +diff --git a/dix/enterleave.c b/dix/enterleave.c
    4.38 +index 17964b00a4..7b7ba1098b 100644
    4.39 +--- a/dix/enterleave.c
    4.40 ++++ b/dix/enterleave.c
    4.41 +@@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
    4.42 + 
    4.43 +     ev->type = DeviceValuator;
    4.44 +     ev->deviceid = dev->id;
    4.45 +-    ev->num_valuators = nval < 3 ? nval : 3;
    4.46 ++    ev->num_valuators = nval < 6 ? nval : 6;
    4.47 +     ev->first_valuator = first;
    4.48 +     switch (ev->num_valuators) {
    4.49 ++    case 6:
    4.50 ++        ev->valuator2 = v->axisVal[first + 5];
    4.51 ++    case 5:
    4.52 ++        ev->valuator2 = v->axisVal[first + 4];
    4.53 ++    case 4:
    4.54 ++        ev->valuator2 = v->axisVal[first + 3];
    4.55 +     case 3:
    4.56 +         ev->valuator2 = v->axisVal[first + 2];
    4.57 +     case 2:
    4.58 +@@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
    4.59 +         ev->valuator0 = v->axisVal[first];
    4.60 +         break;
    4.61 +     }
    4.62 +-    first += ev->num_valuators;
    4.63 + }
    4.64 + 
    4.65 + static void
    4.66 +@@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
    4.67 +         ev->num_buttons = b->numButtons;
    4.68 +         memcpy((char *) ev->buttons, (char *) b->down, 4);
    4.69 +     }
    4.70 +-    else if (k) {
    4.71 ++    if (k) {
    4.72 +         ev->classes_reported |= (1 << KeyClass);
    4.73 +         ev->num_keys = k->xkbInfo->desc->max_key_code -
    4.74 +             k->xkbInfo->desc->min_key_code;
    4.75 +@@ -670,15 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
    4.76 +     }
    4.77 + }
    4.78 + 
    4.79 +-
    4.80 ++/**
    4.81 ++ * The device state notify event is split across multiple 32-byte events.
    4.82 ++ * The first one contains the first 32 button state bits, the first 32
    4.83 ++ * key state bits, and the first 3 valuator values.
    4.84 ++ *
    4.85 ++ * If a device has more than that, the server sends out:
    4.86 ++ * - one deviceButtonStateNotify for buttons 32 and above
    4.87 ++ * - one deviceKeyStateNotify for keys 32 and above
    4.88 ++ * - one deviceValuator event per 6 valuators above valuator 4
    4.89 ++ *
    4.90 ++ * All events but the last one have the deviceid binary ORed with MORE_EVENTS,
    4.91 ++ */
    4.92 + static void
    4.93 + DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
    4.94 + {
    4.95 ++    /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
    4.96 ++     * and one deviceValuator for each 6 valuators */
    4.97 ++    deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
    4.98 +     int evcount = 1;
    4.99 +-    deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
   4.100 +-    deviceStateNotify *ev;
   4.101 +-    deviceKeyStateNotify *kev;
   4.102 +-    deviceButtonStateNotify *bev;
   4.103 ++    deviceStateNotify *ev = sev;
   4.104 + 
   4.105 +     KeyClassPtr k;
   4.106 +     ButtonClassPtr b;
   4.107 +@@ -691,82 +707,49 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
   4.108 + 
   4.109 +     if ((b = dev->button) != NULL) {
   4.110 +         nbuttons = b->numButtons;
   4.111 +-        if (nbuttons > 32)
   4.112 ++        if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
   4.113 +             evcount++;
   4.114 +     }
   4.115 +     if ((k = dev->key) != NULL) {
   4.116 +         nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
   4.117 +-        if (nkeys > 32)
   4.118 ++        if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
   4.119 +             evcount++;
   4.120 +-        if (nbuttons > 0) {
   4.121 +-            evcount++;
   4.122 +-        }
   4.123 +     }
   4.124 +     if ((v = dev->valuator) != NULL) {
   4.125 +         nval = v->numAxes;
   4.126 +-
   4.127 +-        if (nval > 3)
   4.128 +-            evcount++;
   4.129 +-        if (nval > 6) {
   4.130 +-            if (!(k && b))
   4.131 +-                evcount++;
   4.132 +-            if (nval > 9)
   4.133 +-                evcount += ((nval - 7) / 3);
   4.134 +-        }
   4.135 ++        /* first three are encoded in deviceStateNotify, then
   4.136 ++         * it's 6 per deviceValuator event */
   4.137 ++        evcount += ((nval - 3) + 6)/6;
   4.138 +     }
   4.139 + 
   4.140 +-    ev = sev;
   4.141 +-    FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
   4.142 +-
   4.143 +-    if (b != NULL) {
   4.144 +-        FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
   4.145 +-        first += 3;
   4.146 +-        nval -= 3;
   4.147 +-        if (nbuttons > 32) {
   4.148 +-            (ev - 1)->deviceid |= MORE_EVENTS;
   4.149 +-            bev = (deviceButtonStateNotify *) ev++;
   4.150 +-            bev->type = DeviceButtonStateNotify;
   4.151 +-            bev->deviceid = dev->id;
   4.152 +-            memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
   4.153 +-                   DOWN_LENGTH - 4);
   4.154 +-        }
   4.155 +-        if (nval > 0) {
   4.156 +-            (ev - 1)->deviceid |= MORE_EVENTS;
   4.157 +-            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
   4.158 +-            first += 3;
   4.159 +-            nval -= 3;
   4.160 +-        }
   4.161 ++    BUG_RETURN(evcount <= ARRAY_SIZE(sev));
   4.162 ++
   4.163 ++    FixDeviceStateNotify(dev, ev, k, b, v, first);
   4.164 ++
   4.165 ++    if (b != NULL && nbuttons > 32) {
   4.166 ++        deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
   4.167 ++        (ev - 1)->deviceid |= MORE_EVENTS;
   4.168 ++        bev->type = DeviceButtonStateNotify;
   4.169 ++        bev->deviceid = dev->id;
   4.170 ++        memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
   4.171 ++               DOWN_LENGTH - 4);
   4.172 +     }
   4.173 + 
   4.174 +-    if (k != NULL) {
   4.175 +-        FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
   4.176 +-        first += 3;
   4.177 +-        nval -= 3;
   4.178 +-        if (nkeys > 32) {
   4.179 +-            (ev - 1)->deviceid |= MORE_EVENTS;
   4.180 +-            kev = (deviceKeyStateNotify *) ev++;
   4.181 +-            kev->type = DeviceKeyStateNotify;
   4.182 +-            kev->deviceid = dev->id;
   4.183 +-            memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
   4.184 +-        }
   4.185 +-        if (nval > 0) {
   4.186 +-            (ev - 1)->deviceid |= MORE_EVENTS;
   4.187 +-            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
   4.188 +-            first += 3;
   4.189 +-            nval -= 3;
   4.190 +-        }
   4.191 ++    if (k != NULL && nkeys > 32) {
   4.192 ++        deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
   4.193 ++        (ev - 1)->deviceid |= MORE_EVENTS;
   4.194 ++        kev->type = DeviceKeyStateNotify;
   4.195 ++        kev->deviceid = dev->id;
   4.196 ++        memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
   4.197 +     }
   4.198 + 
   4.199 ++    first = 3;
   4.200 ++    nval -= 3;
   4.201 +     while (nval > 0) {
   4.202 +-        FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
   4.203 +-        first += 3;
   4.204 +-        nval -= 3;
   4.205 +-        if (nval > 0) {
   4.206 +-            (ev - 1)->deviceid |= MORE_EVENTS;
   4.207 +-            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
   4.208 +-            first += 3;
   4.209 +-            nval -= 3;
   4.210 +-        }
   4.211 ++        ev->deviceid |= MORE_EVENTS;
   4.212 ++        FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
   4.213 ++        first += 6;
   4.214 ++        nval -= 6;
   4.215 +     }
   4.216 + 
   4.217 +     DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
   4.218 +-- 
   4.219 +GitLab
   4.220 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xorg-server/stuff/CVE-2024-0229-3.patch	Tue Jan 16 20:32:03 2024 +0000
     5.3 @@ -0,0 +1,37 @@
     5.4 +From df3c65706eb169d5938df0052059f3e0d5981b74 Mon Sep 17 00:00:00 2001
     5.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
     5.6 +Date: Thu, 21 Dec 2023 13:48:10 +1000
     5.7 +Subject: [PATCH] Xi: when creating a new ButtonClass, set the number of
     5.8 + buttons
     5.9 +
    5.10 +There's a racy sequence where a master device may copy the button class
    5.11 +from the slave, without ever initializing numButtons. This leads to a
    5.12 +device with zero buttons but a button class which is invalid.
    5.13 +
    5.14 +Let's copy the numButtons value from the source - by definition if we
    5.15 +don't have a button class yet we do not have any other slave devices
    5.16 +with more than this number of buttons anyway.
    5.17 +
    5.18 +CVE-2024-0229, ZDI-CAN-22678
    5.19 +
    5.20 +This vulnerability was discovered by:
    5.21 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    5.22 +---
    5.23 + Xi/exevents.c | 1 +
    5.24 + 1 file changed, 1 insertion(+)
    5.25 +
    5.26 +diff --git a/Xi/exevents.c b/Xi/exevents.c
    5.27 +index 54ea11a938..e161714682 100644
    5.28 +--- a/Xi/exevents.c
    5.29 ++++ b/Xi/exevents.c
    5.30 +@@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
    5.31 +                 to->button = calloc(1, sizeof(ButtonClassRec));
    5.32 +                 if (!to->button)
    5.33 +                     FatalError("[Xi] no memory for class shift.\n");
    5.34 ++                to->button->numButtons = from->button->numButtons;
    5.35 +             }
    5.36 +             else
    5.37 +                 classes->button = NULL;
    5.38 +-- 
    5.39 +GitLab
    5.40 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xorg-server/stuff/CVE-2024-0408.patch	Tue Jan 16 20:32:03 2024 +0000
     6.3 @@ -0,0 +1,60 @@
     6.4 +From e5e8586a12a3ec915673edffa10dc8fe5e15dac3 Mon Sep 17 00:00:00 2001
     6.5 +From: Olivier Fourdan <ofourdan@redhat.com>
     6.6 +Date: Wed, 6 Dec 2023 12:09:41 +0100
     6.7 +Subject: [PATCH] glx: Call XACE hooks on the GLX buffer
     6.8 +
     6.9 +The XSELINUX code will label resources at creation by checking the
    6.10 +access mode. When the access mode is DixCreateAccess, it will call the
    6.11 +function to label the new resource SELinuxLabelResource().
    6.12 +
    6.13 +However, GLX buffers do not go through the XACE hooks when created,
    6.14 +hence leaving the resource actually unlabeled.
    6.15 +
    6.16 +When, later, the client tries to create another resource using that
    6.17 +drawable (like a GC for example), the XSELINUX code would try to use
    6.18 +the security ID of that object which has never been labeled, get a NULL
    6.19 +pointer and crash when checking whether the requested permissions are
    6.20 +granted for subject security ID.
    6.21 +
    6.22 +To avoid the issue, make sure to call the XACE hooks when creating the
    6.23 +GLX buffers.
    6.24 +
    6.25 +Credit goes to Donn Seeley <donn@xmission.com> for providing the patch.
    6.26 +
    6.27 +CVE-2024-0408
    6.28 +
    6.29 +Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
    6.30 +Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
    6.31 +---
    6.32 + glx/glxcmds.c | 8 ++++++++
    6.33 + 1 file changed, 8 insertions(+)
    6.34 +
    6.35 +diff --git a/glx/glxcmds.c b/glx/glxcmds.c
    6.36 +index fc26a2e345..1e46d0c723 100644
    6.37 +--- a/glx/glxcmds.c
    6.38 ++++ b/glx/glxcmds.c
    6.39 +@@ -48,6 +48,7 @@
    6.40 + #include "indirect_util.h"
    6.41 + #include "protocol-versions.h"
    6.42 + #include "glxvndabi.h"
    6.43 ++#include "xace.h"
    6.44 + 
    6.45 + static char GLXServerVendorName[] = "SGI";
    6.46 + 
    6.47 +@@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
    6.48 +     if (!pPixmap)
    6.49 +         return BadAlloc;
    6.50 + 
    6.51 ++    err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP,
    6.52 ++                   pPixmap, RT_NONE, NULL, DixCreateAccess);
    6.53 ++    if (err != Success) {
    6.54 ++        (*pGlxScreen->pScreen->DestroyPixmap) (pPixmap);
    6.55 ++        return err;
    6.56 ++    }
    6.57 ++
    6.58 +     /* Assign the pixmap the same id as the pbuffer and add it as a
    6.59 +      * resource so it and the DRI2 drawable will be reclaimed when the
    6.60 +      * pbuffer is destroyed. */
    6.61 +-- 
    6.62 +GitLab
    6.63 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xorg-server/stuff/CVE-2024-0409.patch	Tue Jan 16 20:32:03 2024 +0000
     7.3 @@ -0,0 +1,56 @@
     7.4 +From 2ef0f1116c65d5cb06d7b6d83f8a1aea702c94f7 Mon Sep 17 00:00:00 2001
     7.5 +From: Olivier Fourdan <ofourdan@redhat.com>
     7.6 +Date: Wed, 6 Dec 2023 11:51:56 +0100
     7.7 +Subject: [PATCH] ephyr,xwayland: Use the proper private key for cursor
     7.8 +
     7.9 +The cursor in DIX is actually split in two parts, the cursor itself and
    7.10 +the cursor bits, each with their own devPrivates.
    7.11 +
    7.12 +The cursor itself includes the cursor bits, meaning that the cursor bits
    7.13 +devPrivates in within structure of the cursor.
    7.14 +
    7.15 +Both Xephyr and Xwayland were using the private key for the cursor bits
    7.16 +to store the data for the cursor, and when using XSELINUX which comes
    7.17 +with its own special devPrivates, the data stored in that cursor bits'
    7.18 +devPrivates would interfere with the XSELINUX devPrivates data and the
    7.19 +SELINUX security ID would point to some other unrelated data, causing a
    7.20 +crash in the XSELINUX code when trying to (re)use the security ID.
    7.21 +
    7.22 +CVE-2024-0409
    7.23 +
    7.24 +Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
    7.25 +Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
    7.26 +---
    7.27 + hw/kdrive/ephyr/ephyrcursor.c | 2 +-
    7.28 + hw/xwayland/xwayland-cursor.c | 2 +-
    7.29 + 2 files changed, 2 insertions(+), 2 deletions(-)
    7.30 +
    7.31 +diff --git a/hw/kdrive/ephyr/ephyrcursor.c b/hw/kdrive/ephyr/ephyrcursor.c
    7.32 +index f991899c50..3f192d034a 100644
    7.33 +--- a/hw/kdrive/ephyr/ephyrcursor.c
    7.34 ++++ b/hw/kdrive/ephyr/ephyrcursor.c
    7.35 +@@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
    7.36 + Bool
    7.37 + ephyrCursorInit(ScreenPtr screen)
    7.38 + {
    7.39 +-    if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS,
    7.40 ++    if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR,
    7.41 +                                sizeof(ephyrCursorRec)))
    7.42 +         return FALSE;
    7.43 + 
    7.44 +diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
    7.45 +index e3c1aaa50c..bd94b0cfbb 100644
    7.46 +--- a/hw/xwayland/xwayland-cursor.c
    7.47 ++++ b/hw/xwayland/xwayland-cursor.c
    7.48 +@@ -431,7 +431,7 @@ static miPointerScreenFuncRec xwl_pointer_screen_funcs = {
    7.49 + Bool
    7.50 + xwl_screen_init_cursor(struct xwl_screen *xwl_screen)
    7.51 + {
    7.52 +-    if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0))
    7.53 ++    if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR, 0))
    7.54 +         return FALSE;
    7.55 + 
    7.56 +     return miPointerInitialize(xwl_screen->screen,
    7.57 +-- 
    7.58 +GitLab
    7.59 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xorg-server/stuff/CVE-2024-21885.patch	Tue Jan 16 20:32:03 2024 +0000
     8.3 @@ -0,0 +1,109 @@
     8.4 +From 4a5e9b1895627d40d26045bd0b7ef3dce503cbd1 Mon Sep 17 00:00:00 2001
     8.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
     8.6 +Date: Thu, 4 Jan 2024 10:01:24 +1000
     8.7 +Subject: [PATCH] Xi: flush hierarchy events after adding/removing master
     8.8 + devices
     8.9 +
    8.10 +The `XISendDeviceHierarchyEvent()` function allocates space to store up
    8.11 +to `MAXDEVICES` (256) `xXIHierarchyInfo` structures in `info`.
    8.12 +
    8.13 +If a device with a given ID was removed and a new device with the same
    8.14 +ID added both in the same operation, the single device ID will lead to
    8.15 +two info structures being written to `info`.
    8.16 +
    8.17 +Since this case can occur for every device ID at once, a total of two
    8.18 +times `MAXDEVICES` info structures might be written to the allocation.
    8.19 +
    8.20 +To avoid it, once one add/remove master is processed, send out the
    8.21 +device hierarchy event for the current state and continue. That event
    8.22 +thus only ever has exactly one of either added/removed in it (and
    8.23 +optionally slave attached/detached).
    8.24 +
    8.25 +CVE-2024-21885, ZDI-CAN-22744
    8.26 +
    8.27 +This vulnerability was discovered by:
    8.28 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    8.29 +---
    8.30 + Xi/xichangehierarchy.c | 27 ++++++++++++++++++++++-----
    8.31 + 1 file changed, 22 insertions(+), 5 deletions(-)
    8.32 +
    8.33 +diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
    8.34 +index d2d985848d..72d00451e3 100644
    8.35 +--- a/Xi/xichangehierarchy.c
    8.36 ++++ b/Xi/xichangehierarchy.c
    8.37 +@@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client)
    8.38 +     size_t len;			/* length of data remaining in request */
    8.39 +     int rc = Success;
    8.40 +     int flags[MAXDEVICES] = { 0 };
    8.41 ++    enum {
    8.42 ++        NO_CHANGE,
    8.43 ++        FLUSH,
    8.44 ++        CHANGED,
    8.45 ++    } changes = NO_CHANGE;
    8.46 + 
    8.47 +     REQUEST(xXIChangeHierarchyReq);
    8.48 +     REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
    8.49 +@@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client)
    8.50 +             rc = add_master(client, c, flags);
    8.51 +             if (rc != Success)
    8.52 +                 goto unwind;
    8.53 +-        }
    8.54 ++            changes = FLUSH;
    8.55 +             break;
    8.56 ++        }
    8.57 +         case XIRemoveMaster:
    8.58 +         {
    8.59 +             xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
    8.60 +@@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client)
    8.61 +             rc = remove_master(client, r, flags);
    8.62 +             if (rc != Success)
    8.63 +                 goto unwind;
    8.64 +-        }
    8.65 ++            changes = FLUSH;
    8.66 +             break;
    8.67 ++        }
    8.68 +         case XIDetachSlave:
    8.69 +         {
    8.70 +             xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
    8.71 +@@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client)
    8.72 +             rc = detach_slave(client, c, flags);
    8.73 +             if (rc != Success)
    8.74 +                 goto unwind;
    8.75 +-        }
    8.76 ++            changes = CHANGED;
    8.77 +             break;
    8.78 ++        }
    8.79 +         case XIAttachSlave:
    8.80 +         {
    8.81 +             xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
    8.82 +@@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
    8.83 +             rc = attach_slave(client, c, flags);
    8.84 +             if (rc != Success)
    8.85 +                 goto unwind;
    8.86 ++            changes = CHANGED;
    8.87 ++            break;
    8.88 +         }
    8.89 ++        default:
    8.90 +             break;
    8.91 +         }
    8.92 + 
    8.93 ++        if (changes == FLUSH) {
    8.94 ++            XISendDeviceHierarchyEvent(flags);
    8.95 ++            memset(flags, 0, sizeof(flags));
    8.96 ++            changes = NO_CHANGE;
    8.97 ++        }
    8.98 ++
    8.99 +         len -= any->length * 4;
   8.100 +         any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
   8.101 +     }
   8.102 + 
   8.103 +  unwind:
   8.104 +-
   8.105 +-    XISendDeviceHierarchyEvent(flags);
   8.106 ++    if (changes != NO_CHANGE)
   8.107 ++        XISendDeviceHierarchyEvent(flags);
   8.108 +     return rc;
   8.109 + }
   8.110 +-- 
   8.111 +GitLab
   8.112 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xorg-server/stuff/CVE-2024-21886-1.patch	Tue Jan 16 20:32:03 2024 +0000
     9.3 @@ -0,0 +1,70 @@
     9.4 +From bc1fdbe46559dd947674375946bbef54dd0ce36b Mon Sep 17 00:00:00 2001
     9.5 +From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
     9.6 +Date: Fri, 22 Dec 2023 18:28:31 +0100
     9.7 +Subject: [PATCH] Xi: do not keep linked list pointer during recursion
     9.8 +
     9.9 +The `DisableDevice()` function is called whenever an enabled device
    9.10 +is disabled and it moves the device from the `inputInfo.devices` linked
    9.11 +list to the `inputInfo.off_devices` linked list.
    9.12 +
    9.13 +However, its link/unlink operation has an issue during the recursive
    9.14 +call to `DisableDevice()` due to the `prev` pointer pointing to a
    9.15 +removed device.
    9.16 +
    9.17 +This issue leads to a length mismatch between the total number of
    9.18 +devices and the number of device in the list, leading to a heap
    9.19 +overflow and, possibly, to local privilege escalation.
    9.20 +
    9.21 +Simplify the code that checked whether the device passed to
    9.22 +`DisableDevice()` was in `inputInfo.devices` or not and find the
    9.23 +previous device after the recursion.
    9.24 +
    9.25 +CVE-2024-21886, ZDI-CAN-22840
    9.26 +
    9.27 +This vulnerability was discovered by:
    9.28 +Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    9.29 +---
    9.30 + dix/devices.c | 15 ++++++++++++---
    9.31 + 1 file changed, 12 insertions(+), 3 deletions(-)
    9.32 +
    9.33 +diff --git a/dix/devices.c b/dix/devices.c
    9.34 +index dca98c8d1b..389d28a23c 100644
    9.35 +--- a/dix/devices.c
    9.36 ++++ b/dix/devices.c
    9.37 +@@ -453,14 +453,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
    9.38 + {
    9.39 +     DeviceIntPtr *prev, other;
    9.40 +     BOOL enabled;
    9.41 ++    BOOL dev_in_devices_list = FALSE;
    9.42 +     int flags[MAXDEVICES] = { 0 };
    9.43 + 
    9.44 +     if (!dev->enabled)
    9.45 +         return TRUE;
    9.46 + 
    9.47 +-    for (prev = &inputInfo.devices;
    9.48 +-         *prev && (*prev != dev); prev = &(*prev)->next);
    9.49 +-    if (*prev != dev)
    9.50 ++    for (other = inputInfo.devices; other; other = other->next) {
    9.51 ++        if (other == dev) {
    9.52 ++            dev_in_devices_list = TRUE;
    9.53 ++            break;
    9.54 ++        }
    9.55 ++    }
    9.56 ++
    9.57 ++    if (!dev_in_devices_list)
    9.58 +         return FALSE;
    9.59 + 
    9.60 +     TouchEndPhysicallyActiveTouches(dev);
    9.61 +@@ -511,6 +517,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
    9.62 +     LeaveWindow(dev);
    9.63 +     SetFocusOut(dev);
    9.64 + 
    9.65 ++    for (prev = &inputInfo.devices;
    9.66 ++         *prev && (*prev != dev); prev = &(*prev)->next);
    9.67 ++
    9.68 +     *prev = dev->next;
    9.69 +     dev->next = inputInfo.off_devices;
    9.70 +     inputInfo.off_devices = dev;
    9.71 +-- 
    9.72 +GitLab
    9.73 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xorg-server/stuff/CVE-2024-21886-2.patch	Tue Jan 16 20:32:03 2024 +0000
    10.3 @@ -0,0 +1,53 @@
    10.4 +From 26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8 Mon Sep 17 00:00:00 2001
    10.5 +From: Peter Hutterer <peter.hutterer@who-t.net>
    10.6 +Date: Fri, 5 Jan 2024 09:40:27 +1000
    10.7 +Subject: [PATCH] dix: when disabling a master, float disabled slaved devices
    10.8 + too
    10.9 +
   10.10 +Disabling a master device floats all slave devices but we didn't do this
   10.11 +to already-disabled slave devices. As a result those devices kept their
   10.12 +reference to the master device resulting in access to already freed
   10.13 +memory if the master device was removed before the corresponding slave
   10.14 +device.
   10.15 +
   10.16 +And to match this behavior, also forcibly reset that pointer during
   10.17 +CloseDownDevices().
   10.18 +
   10.19 +Related to CVE-2024-21886, ZDI-CAN-22840
   10.20 +---
   10.21 + dix/devices.c | 12 ++++++++++++
   10.22 + 1 file changed, 12 insertions(+)
   10.23 +
   10.24 +diff --git a/dix/devices.c b/dix/devices.c
   10.25 +index 389d28a23c..84a6406d13 100644
   10.26 +--- a/dix/devices.c
   10.27 ++++ b/dix/devices.c
   10.28 +@@ -483,6 +483,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
   10.29 +                 flags[other->id] |= XISlaveDetached;
   10.30 +             }
   10.31 +         }
   10.32 ++
   10.33 ++        for (other = inputInfo.off_devices; other; other = other->next) {
   10.34 ++            if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
   10.35 ++                AttachDevice(NULL, other, NULL);
   10.36 ++                flags[other->id] |= XISlaveDetached;
   10.37 ++            }
   10.38 ++        }
   10.39 +     }
   10.40 +     else {
   10.41 +         for (other = inputInfo.devices; other; other = other->next) {
   10.42 +@@ -1088,6 +1095,11 @@ CloseDownDevices(void)
   10.43 +             dev->master = NULL;
   10.44 +     }
   10.45 + 
   10.46 ++    for (dev = inputInfo.off_devices; dev; dev = dev->next) {
   10.47 ++        if (!IsMaster(dev) && !IsFloating(dev))
   10.48 ++            dev->master = NULL;
   10.49 ++    }
   10.50 ++
   10.51 +     CloseDeviceList(&inputInfo.devices);
   10.52 +     CloseDeviceList(&inputInfo.off_devices);
   10.53 + 
   10.54 +-- 
   10.55 +GitLab
   10.56 +