Blame SOURCES/0006-Xext-free-the-XvRTVideoNotify-when-turning-off-from-.patch

72411e
From a42635ee3c01f71a49052d83a372933504c9db04 Mon Sep 17 00:00:00 2001
72411e
From: Peter Hutterer <peter.hutterer@who-t.net>
72411e
Date: Wed, 30 Nov 2022 11:20:40 +1000
72411e
Subject: [PATCH xserver 6/7] Xext: free the XvRTVideoNotify when turning off
72411e
 from the same client
72411e
72411e
This fixes a use-after-free bug:
72411e
72411e
When a client first calls XvdiSelectVideoNotify() on a drawable with a
72411e
TRUE onoff argument, a struct XvVideoNotifyRec is allocated. This struct
72411e
is added twice to the resources:
72411e
  - as the drawable's XvRTVideoNotifyList. This happens only once per
72411e
    drawable, subsequent calls append to this list.
72411e
  - as the client's XvRTVideoNotify. This happens for every client.
72411e
72411e
The struct keeps the ClientPtr around once it has been added for a
72411e
client. The idea, presumably, is that if the client disconnects we can remove
72411e
all structs from the drawable's list that match the client (by resetting
72411e
the ClientPtr to NULL), but if the drawable is destroyed we can remove
72411e
and free the whole list.
72411e
72411e
However, if the same client then calls XvdiSelectVideoNotify() on the
72411e
same drawable with a FALSE onoff argument, only the ClientPtr on the
72411e
existing struct was set to NULL. The struct itself remained in the
72411e
client's resources.
72411e
72411e
If the drawable is now destroyed, the resource system invokes
72411e
XvdiDestroyVideoNotifyList which frees the whole list for this drawable
72411e
- including our struct. This function however does not free the resource
72411e
for the client since our ClientPtr is NULL.
72411e
72411e
Later, when the client is destroyed and the resource system invokes
72411e
XvdiDestroyVideoNotify, we unconditionally set the ClientPtr to NULL. On
72411e
a struct that has been freed previously. This is generally frowned upon.
72411e
72411e
Fix this by calling FreeResource() on the second call instead of merely
72411e
setting the ClientPtr to NULL. This removes the struct from the client
72411e
resources (but not from the list), ensuring that it won't be accessed
72411e
again when the client quits.
72411e
72411e
Note that the assignment tpn->client = NULL; is superfluous since the
72411e
XvdiDestroyVideoNotify function will do this anyway. But it's left for
72411e
clarity and to match a similar invocation in XvdiSelectPortNotify.
72411e
72411e
CVE-2022-46342, ZDI-CAN 19400
72411e
72411e
This vulnerability was discovered by:
72411e
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
72411e
72411e
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
72411e
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
72411e
---
72411e
 Xext/xvmain.c | 4 +++-
72411e
 1 file changed, 3 insertions(+), 1 deletion(-)
72411e
72411e
diff --git a/Xext/xvmain.c b/Xext/xvmain.c
72411e
index f627471938..2a08f8744a 100644
72411e
--- a/Xext/xvmain.c
72411e
+++ b/Xext/xvmain.c
72411e
@@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
72411e
         tpn = pn;
72411e
         while (tpn) {
72411e
             if (tpn->client == client) {
72411e
-                if (!onoff)
72411e
+                if (!onoff) {
72411e
                     tpn->client = NULL;
72411e
+                    FreeResource(tpn->id, XvRTVideoNotify);
72411e
+                }
72411e
                 return Success;
72411e
             }
72411e
             if (!tpn->client)
72411e
--
72411e
2.38.1