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

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