xserver: Branch 'server-21.1-branch' - 7 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Dec 14 01:38:46 UTC 2022


 Xext/saver.c       |    2 +-
 Xext/xtest.c       |    5 +++--
 Xext/xvmain.c      |    4 +++-
 Xi/xipassivegrab.c |   22 ++++++++++++++--------
 Xi/xiproperty.c    |    9 +++++++--
 dix/property.c     |    3 ++-
 xkb/xkbUtils.c     |    1 +
 7 files changed, 31 insertions(+), 15 deletions(-)

New commits:
commit e860bbce4fdb169e84033529331ae2666e679de7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Dec 5 15:55:54 2022 +1000

    xkb: reset the radio_groups pointer to NULL after freeing it
    
    Unlike other elements of the keymap, this pointer was freed but not
    reset. On a subsequent XkbGetKbdByName request, the server may access
    already freed memory.
    
    CVE-2022-4283, ZDI-CAN-19530
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit ccdd431cd8f1cabae9d744f0514b6533c438908c)

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 8975ade8d..9bc51fc71 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1327,6 +1327,7 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst)
         }
         else {
             free(dst->names->radio_groups);
+            dst->names->radio_groups = NULL;
         }
         dst->names->num_rg = src->names->num_rg;
 
commit 8a1fa008b2f90abce6cabb27d9bc2ed76d07b678
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 29 13:26:57 2022 +1000

    Xi: avoid integer truncation in length check of ProcXIChangeProperty
    
    This fixes an OOB read and the resulting information disclosure.
    
    Length calculation for the request was clipped to a 32-bit integer. With
    the correct stuff->num_items value the expected request size was
    truncated, passing the REQUEST_FIXED_SIZE check.
    
    The server then proceeded with reading at least stuff->num_items bytes
    (depending on stuff->format) from the request and stuffing whatever it
    finds into the property. In the process it would also allocate at least
    stuff->num_items bytes, i.e. 4GB.
    
    The same bug exists in ProcChangeProperty and ProcXChangeDeviceProperty,
    so let's fix that too.
    
    CVE-2022-46344, ZDI-CAN 19405
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 8f454b793e1f13c99872c15f0eed1d7f3b823fe8)

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 68c362c62..066ba21fb 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -890,7 +890,7 @@ ProcXChangeDeviceProperty(ClientPtr client)
     REQUEST(xChangeDevicePropertyReq);
     DeviceIntPtr dev;
     unsigned long len;
-    int totalSize;
+    uint64_t totalSize;
     int rc;
 
     REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
@@ -1130,7 +1130,7 @@ ProcXIChangeProperty(ClientPtr client)
 {
     int rc;
     DeviceIntPtr dev;
-    int totalSize;
+    uint64_t totalSize;
     unsigned long len;
 
     REQUEST(xXIChangePropertyReq);
diff --git a/dix/property.c b/dix/property.c
index 94ef5a0ec..acce94b2c 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -205,7 +205,8 @@ ProcChangeProperty(ClientPtr client)
     WindowPtr pWin;
     char format, mode;
     unsigned long len;
-    int sizeInBytes, totalSize, err;
+    int sizeInBytes, err;
+    uint64_t totalSize;
 
     REQUEST(xChangePropertyReq);
 
commit 40f431de8a76f737c68ae659fee8472583f15e49
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 29 13:24:00 2022 +1000

    Xi: return an error from XI property changes if verification failed
    
    Both ProcXChangeDeviceProperty and ProcXIChangeProperty checked the
    property for validity but didn't actually return the potential error.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b8a84cb0f2807b07ab70ca9915fcdee21301b8ca)

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index a36f7d61d..68c362c62 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -902,6 +902,8 @@ ProcXChangeDeviceProperty(ClientPtr client)
 
     rc = check_change_property(client, stuff->property, stuff->type,
                                stuff->format, stuff->mode, stuff->nUnits);
+    if (rc != Success)
+        return rc;
 
     len = stuff->nUnits;
     if (len > (bytes_to_int32(0xffffffff - sizeof(xChangeDevicePropertyReq))))
@@ -1141,6 +1143,9 @@ ProcXIChangeProperty(ClientPtr client)
 
     rc = check_change_property(client, stuff->property, stuff->type,
                                stuff->format, stuff->mode, stuff->num_items);
+    if (rc != Success)
+        return rc;
+
     len = stuff->num_items;
     if (len > bytes_to_int32(0xffffffff - sizeof(xXIChangePropertyReq)))
         return BadLength;
commit d6c7de9eadca980c8ce3b3b7752b67bfa95e6f31
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 29 14:53:07 2022 +1000

    Xext: free the screen saver resource when replacing it
    
    This fixes a use-after-free bug:
    
    When a client first calls ScreenSaverSetAttributes(), a struct
    ScreenSaverAttrRec is allocated and added to the client's
    resources.
    
    When the same client calls ScreenSaverSetAttributes() again, a new
    struct ScreenSaverAttrRec is allocated, replacing the old struct. The
    old struct was freed but not removed from the clients resources.
    
    Later, when the client is destroyed the resource system invokes
    ScreenSaverFreeAttr and attempts to clean up the already freed struct.
    
    Fix this by letting the resource system free the old attrs instead.
    
    CVE-2022-46343, ZDI-CAN 19404
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 842ca3ccef100ce010d1d8f5f6d6cc1915055900)

diff --git a/Xext/saver.c b/Xext/saver.c
index f813ba08d..fd6153c31 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client)
         pVlist++;
     }
     if (pPriv->attr)
-        FreeScreenAttr(pPriv->attr);
+        FreeResource(pPriv->attr->resource, AttrType);
     pPriv->attr = pAttr;
     pAttr->resource = FakeClientID(client->index);
     if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
commit 67927cc41f452228188bbe2aa34a9ee4a9ce0c6b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Nov 30 11:20:40 2022 +1000

    Xext: free the XvRTVideoNotify when turning off from the same client
    
    This fixes a use-after-free bug:
    
    When a client first calls XvdiSelectVideoNotify() on a drawable with a
    TRUE onoff argument, a struct XvVideoNotifyRec is allocated. This struct
    is added twice to the resources:
      - as the drawable's XvRTVideoNotifyList. This happens only once per
        drawable, subsequent calls append to this list.
      - as the client's XvRTVideoNotify. This happens for every client.
    
    The struct keeps the ClientPtr around once it has been added for a
    client. The idea, presumably, is that if the client disconnects we can remove
    all structs from the drawable's list that match the client (by resetting
    the ClientPtr to NULL), but if the drawable is destroyed we can remove
    and free the whole list.
    
    However, if the same client then calls XvdiSelectVideoNotify() on the
    same drawable with a FALSE onoff argument, only the ClientPtr on the
    existing struct was set to NULL. The struct itself remained in the
    client's resources.
    
    If the drawable is now destroyed, the resource system invokes
    XvdiDestroyVideoNotifyList which frees the whole list for this drawable
    - including our struct. This function however does not free the resource
    for the client since our ClientPtr is NULL.
    
    Later, when the client is destroyed and the resource system invokes
    XvdiDestroyVideoNotify, we unconditionally set the ClientPtr to NULL. On
    a struct that has been freed previously. This is generally frowned upon.
    
    Fix this by calling FreeResource() on the second call instead of merely
    setting the ClientPtr to NULL. This removes the struct from the client
    resources (but not from the list), ensuring that it won't be accessed
    again when the client quits.
    
    Note that the assignment tpn->client = NULL; is superfluous since the
    XvdiDestroyVideoNotify function will do this anyway. But it's left for
    clarity and to match a similar invocation in XvdiSelectPortNotify.
    
    CVE-2022-46342, ZDI-CAN 19400
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b79f32b57cc0c1186b2899bce7cf89f7b325161b)

diff --git a/Xext/xvmain.c b/Xext/xvmain.c
index f62747193..2a08f8744 100644
--- a/Xext/xvmain.c
+++ b/Xext/xvmain.c
@@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
         tpn = pn;
         while (tpn) {
             if (tpn->client == client) {
-                if (!onoff)
+                if (!onoff) {
                     tpn->client = NULL;
+                    FreeResource(tpn->id, XvRTVideoNotify);
+                }
                 return Success;
             }
             if (!tpn->client)
commit a6c0d7b142e762a6b9934a23e060ea91ff5afcea
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 29 13:55:32 2022 +1000

    Xi: disallow passive grabs with a detail > 255
    
    The XKB protocol effectively prevents us from ever using keycodes above
    255. For buttons it's theoretically possible but realistically too niche
    to worry about. For all other passive grabs, the detail must be zero
    anyway.
    
    This fixes an OOB write:
    
    ProcXIPassiveUngrabDevice() calls DeletePassiveGrabFromList with a
    temporary grab struct which contains tempGrab->detail.exact = stuff->detail.
    For matching existing grabs, DeleteDetailFromMask is called with the
    stuff->detail value. This function creates a new mask with the one bit
    representing stuff->detail cleared.
    
    However, the array size for the new mask is 8 * sizeof(CARD32) bits,
    thus any detail above 255 results in an OOB array write.
    
    CVE-2022-46341, ZDI-CAN 19381
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 51eb63b0ee1509c6c6b8922b0e4aa037faa6f78b)

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 2769fb7c9..c9ac2f855 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -137,6 +137,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
         return BadValue;
     }
 
+    /* XI2 allows 32-bit keycodes but thanks to XKB we can never
+     * implement this. Just return an error for all keycodes that
+     * cannot work anyway, same for buttons > 255. */
+    if (stuff->detail > 255)
+        return XIAlreadyGrabbed;
+
     if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
                                stuff->mask_len * 4) != Success)
         return BadValue;
@@ -207,14 +213,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
                                 &param, XI2, &mask);
             break;
         case XIGrabtypeKeycode:
-            /* XI2 allows 32-bit keycodes but thanks to XKB we can never
-             * implement this. Just return an error for all keycodes that
-             * cannot work anyway */
-            if (stuff->detail > 255)
-                status = XIAlreadyGrabbed;
-            else
-                status = GrabKey(client, dev, mod_dev, stuff->detail,
-                                 &param, XI2, &mask);
+            status = GrabKey(client, dev, mod_dev, stuff->detail,
+                             &param, XI2, &mask);
             break;
         case XIGrabtypeEnter:
         case XIGrabtypeFocusIn:
@@ -334,6 +334,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
         return BadValue;
     }
 
+    /* We don't allow passive grabs for details > 255 anyway */
+    if (stuff->detail > 255) {
+        client->errorValue = stuff->detail;
+        return BadValue;
+    }
+
     rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
     if (rc != Success)
         return rc;
commit 936d34bdff4c479ccd0405fc221ff8e4c6c7014d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Nov 29 12:55:45 2022 +1000

    Xtest: disallow GenericEvents in XTestSwapFakeInput
    
    XTestSwapFakeInput assumes all events in this request are
    sizeof(xEvent) and iterates through these in 32-byte increments.
    However, a GenericEvent may be of arbitrary length longer than 32 bytes,
    so any GenericEvent in this list would result in subsequent events to be
    misparsed.
    
    Additional, the swapped event is written into a stack-allocated struct
    xEvent (size 32 bytes). For any GenericEvent longer than 32 bytes,
    swapping the event may thus smash the stack like an avocado on toast.
    
    Catch this case early and return BadValue for any GenericEvent.
    Which is what would happen in unswapped setups anyway since XTest
    doesn't support GenericEvent.
    
    CVE-2022-46340, ZDI-CAN 19265
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b320ca0ffe4c0c872eeb3a93d9bde21f765c7c63)

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 540d270a1..e5d38aa61 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -502,10 +502,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)
 
     nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
     for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
+        int evtype = ev->u.u.type & 0x177;
         /* Swap event */
-        proc = EventSwapVector[ev->u.u.type & 0177];
+        proc = EventSwapVector[evtype];
         /* no swapping proc; invalid event type? */
-        if (!proc || proc == NotImplemented) {
+        if (!proc || proc == NotImplemented || evtype == GenericEvent) {
             client->errorValue = ev->u.u.type;
             return BadValue;
         }


More information about the xorg-commit mailing list