diff --git a/U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch b/U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch new file mode 100644 index 0000000..d9df3ea --- /dev/null +++ b/U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch @@ -0,0 +1,169 @@ +From a9e845809bcaae22496bc8aa3ca252b410d5f39b Mon Sep 17 00:00:00 2001 +From: Matthieu Herrb +Date: Fri, 11 Nov 2022 18:55:23 +0100 +Subject: [PATCH] Fix 797755 Allow X*IfEvent() to reenter libX11 + +- the activation logic is reversed +- there is also _XInternalLockDisplay() that needs protection +- I've found cases (in fvwm2) where the callback calls XCheckIfEvent() + recursively. So the flag needs to be a counter. + +Reviewed-by: Adam Jackson +--- + include/X11/Xlibint.h | 2 +- + src/ChkIfEv.c | 4 ++-- + src/IfEvent.c | 4 ++-- + src/OpenDis.c | 2 +- + src/PeekIfEv.c | 4 ++-- + src/locking.c | 27 ++++++++++++++++++++++----- + 6 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h +index b4275ebd..e20c4833 100644 +--- a/include/X11/Xlibint.h ++++ b/include/X11/Xlibint.h +@@ -207,7 +207,7 @@ struct _XDisplay + + XIOErrorExitHandler exit_handler; + void *exit_handler_data; +- Bool in_ifevent; ++ CARD32 in_ifevent; + }; + + #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) +diff --git a/src/ChkIfEv.c b/src/ChkIfEv.c +index 327b5eaf..1bbcba5b 100644 +--- a/src/ChkIfEv.c ++++ b/src/ChkIfEv.c +@@ -49,8 +49,8 @@ Bool XCheckIfEvent ( + unsigned long qe_serial = 0; + int n; /* time through count */ + ++ dpy->in_ifevent++; + LockDisplay(dpy); +- dpy->in_ifevent = True; + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; +@@ -80,7 +80,7 @@ Bool XCheckIfEvent ( + /* another thread has snatched this event */ + prev = NULL; + } +- dpy->in_ifevent = False; ++ dpy->in_ifevent--; + UnlockDisplay(dpy); + return False; + } +diff --git a/src/IfEvent.c b/src/IfEvent.c +index a0aed7e3..593e7acf 100644 +--- a/src/IfEvent.c ++++ b/src/IfEvent.c +@@ -48,8 +48,8 @@ XIfEvent ( + register _XQEvent *qelt, *prev; + unsigned long qe_serial = 0; + ++ dpy->in_ifevent++; + LockDisplay(dpy); +- dpy->in_ifevent = True; + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; +@@ -60,7 +60,7 @@ XIfEvent ( + *event = qelt->event; + _XDeq(dpy, prev, qelt); + _XStoreEventCookie(dpy, event); +- dpy->in_ifevent = False; ++ dpy->in_ifevent--; + UnlockDisplay(dpy); + return 0; + } +diff --git a/src/OpenDis.c b/src/OpenDis.c +index e1bc2a30..17dc4cb2 100644 +--- a/src/OpenDis.c ++++ b/src/OpenDis.c +@@ -189,7 +189,7 @@ XOpenDisplay ( + dpy->xcmisc_opcode = 0; + dpy->xkb_info = NULL; + dpy->exit_handler_data = NULL; +- dpy->in_ifevent = False; ++ dpy->in_ifevent = 0; + + /* + * Setup other information in this display structure. +diff --git a/src/PeekIfEv.c b/src/PeekIfEv.c +index c4e8af0d..7e09c00b 100644 +--- a/src/PeekIfEv.c ++++ b/src/PeekIfEv.c +@@ -49,8 +49,8 @@ XPeekIfEvent ( + register _XQEvent *prev, *qelt; + unsigned long qe_serial = 0; + ++ dpy->in_ifevent++; + LockDisplay(dpy); +- dpy->in_ifevent = True; + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; +@@ -64,7 +64,7 @@ XPeekIfEvent ( + _XStoreEventCookie(dpy, ©); + *event = copy; + } +- dpy->in_ifevent = False; ++ dpy->in_ifevent--; + UnlockDisplay(dpy); + return 0; + } +diff --git a/src/locking.c b/src/locking.c +index bdc07011..690b2bf6 100644 +--- a/src/locking.c ++++ b/src/locking.c +@@ -465,17 +465,33 @@ static void _XIfEventLockDisplay( + /* assert(dpy->in_ifevent); */ + } + ++static void _XInternalLockDisplay( ++ Display *dpy, ++ Bool wskip ++ XTHREADS_FILE_LINE_ARGS ++ ); ++ ++static void _XIfEventInternalLockDisplay( ++ Display *dpy, ++ Bool wskip ++ XTHREADS_FILE_LINE_ARGS ++ ) ++{ ++ /* assert(dpy->in_ifevent); */ ++} ++ + static void _XIfEventUnlockDisplay( + Display *dpy + XTHREADS_FILE_LINE_ARGS + ) + { +- if (dpy->in_ifevent) ++ if (dpy->in_ifevent == 0) { ++ dpy->lock_fns->lock_display = _XLockDisplay; ++ dpy->lock_fns->unlock_display = _XUnlockDisplay; ++ dpy->lock->internal_lock_display = _XInternalLockDisplay; ++ UnlockDisplay(dpy); ++ } else + return; +- +- dpy->lock_fns->lock_display = _XLockDisplay; +- dpy->lock_fns->unlock_display = _XUnlockDisplay; +- UnlockDisplay(dpy); + } + + static void _XLockDisplay( +@@ -507,6 +523,7 @@ static void _XLockDisplay( + if (dpy->in_ifevent) { + dpy->lock_fns->lock_display = _XIfEventLockDisplay; + dpy->lock_fns->unlock_display = _XIfEventUnlockDisplay; ++ dpy->lock->internal_lock_display = _XIfEventInternalLockDisplay; + } + } + +-- +2.35.3 + diff --git a/libX11.changes b/libX11.changes index 86f660c..76c0eed 100644 --- a/libX11.changes +++ b/libX11.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Sat Nov 26 09:56:03 UTC 2022 - Stefan Dirsch + +- U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch + * fixed Firefox freezes (regression since 1.8.2) (boo#1205778) + ------------------------------------------------------------------- Fri Nov 11 09:05:09 UTC 2022 - Stefan Dirsch diff --git a/libX11.spec b/libX11.spec index cfa21f0..afb1c7f 100644 --- a/libX11.spec +++ b/libX11.spec @@ -32,6 +32,7 @@ Patch1: p_xlib_skip_ext_env.diff # PATCH-FIX-UPSTREAM en-locales.diff fdo#48596 bnc#388711 -- Add missing data for more en locales Patch2: en-locales.diff Patch3: u_no-longer-crash-in-XVisualIDFromVisual.patch +Patch4: U_Fix-797755-Allow-X-IfEvent-to-reenter-libX11.patch BuildRequires: fdupes BuildRequires: libtool BuildRequires: pkgconfig @@ -135,6 +136,7 @@ test -f nls/ja.S90/XLC_LOCALE.pre && exit 1 %patch1 %patch2 %patch3 -p1 +%patch4 -p1 %build %configure \