summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorCebtenzzre2020-08-18 20:41:50 -0400
committerCebtenzzre2020-08-18 20:41:50 -0400
commit565dfcf7686cb69e99f2e9aca56999a19811d7b9 (patch)
tree1cd95903943e86461ffc8c7de83a396b37f54e32
parent28af81ce92fb5ed40c535916380f64ccae312b9c (diff)
downloadaur-565dfcf7686cb69e99f2e9aca56999a19811d7b9.tar.gz
Add patch "Fix poll_for_response race condition"
Upstream merge request: https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/34
-rw-r--r--.SRCINFO2
-rw-r--r--0001-Fix-poll_for_response-race-condition.patch114
-rw-r--r--PKGBUILD3
3 files changed, 119 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
index d08e8a7a24df..0f615eaa9a1c 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -13,6 +13,7 @@ pkgbase = libx11-threadsafe
conflicts = libx11=1.6.11
source = https://xorg.freedesktop.org//releases/individual/lib/libX11-1.6.11.tar.bz2
source = https://xorg.freedesktop.org//releases/individual/lib/libX11-1.6.11.tar.bz2.sig
+ source = 0001-Fix-poll_for_response-race-condition.patch
source = threadsafe.patch
validpgpkeys = 4A193C06D35E7C670FA4EF0BA2FB9E081F2D130E
validpgpkeys = C41C985FDCF1E5364576638B687393EE37D128F8
@@ -20,6 +21,7 @@ pkgbase = libx11-threadsafe
validpgpkeys = 995ED5C8A6138EB0961F18474C09DD83CAAA50B2
sha512sums = 2cb4e215c1e3ccb327e02586844f8c426068536a0f472a39f12191feace607f61a6a08586f03758248199678c2f6897a984b0f1222bc0d68fd2e02702f4ce0bf
sha512sums = SKIP
+ sha512sums = 8e45cf24ee3eaa735d79cfe768b87917be86ada8ae8688f44e1d914c52ac39be9815986432893d73b5c931ac2dd9a849d47bf2b2063b440f57a67c7d9ca5cc1f
sha512sums = 625e747ddbbd6d84d9198199ecb9d93aad4e39c2b20b618bb2cc283c4c5aa3dd83bc80d45b002b612ffff2c70bf8d7cf1d07152097221b0c144a6cc06e0f5d63
pkgname = libx11-threadsafe
diff --git a/0001-Fix-poll_for_response-race-condition.patch b/0001-Fix-poll_for_response-race-condition.patch
new file mode 100644
index 000000000000..f8b3d3d19d37
--- /dev/null
+++ b/0001-Fix-poll_for_response-race-condition.patch
@@ -0,0 +1,114 @@
+From 8b45f9589b3eb1ff46d16c774b017794e553db8e Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Wed, 29 Jan 2020 09:06:54 +0000
+Subject: [PATCH] Fix poll_for_response race condition
+
+In poll_for_response is it possible that event replies are skipped
+and a more up to date message reply is returned.
+This will cause next poll_for_event call to fail aborting the program.
+
+This was proved using some slow ssh tunnel or using some program
+to slow down server replies (I used a combination of xtrace and strace).
+
+How the race happens:
+- program enters into poll_for_response;
+- poll_for_event is called but the server didn't still send the reply;
+- pending_requests is not NULL because we send a request (see call
+ to append_pending_request in _XSend);
+- xcb_poll_for_reply64 is called from poll_for_response;
+- xcb_poll_for_reply64 will read from server, at this point
+ server reply with an event (say sequence N) and the reply to our
+ last request (say sequence N+1);
+- xcb_poll_for_reply64 returns the reply for the request we asked;
+- last_request_read is set to N+1 sequence in poll_for_response;
+- poll_for_response returns the response to the request;
+- poll_for_event is called (for instance from another poll_for_response);
+- event with sequence N is retrieved;
+- the N sequence is widen, however, as the "new" number computed from
+ last_request_read is less than N the number is widened to N + 2^32
+ (assuming last_request_read is still contained in 32 bit);
+- poll_for_event enters the nested if statement as req is NULL;
+- we compare the widen N (which now does not fit into 32 bit) with
+ request (which fits into 32 bit) hitting the throw_thread_fail_assert.
+
+To avoid the race condition and to avoid the sequence to go back
+I check again for new events after getting the response and
+return this last event if present saving the reply to return it
+later.
+
+To test the race and the fix it's helpful to add a delay (I used a
+"usleep(5000)") before calling xcb_poll_for_reply64.
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ src/Xxcbint.h | 1 +
+ src/xcb_io.c | 28 ++++++++++++++++++++++++++--
+ 2 files changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/src/Xxcbint.h b/src/Xxcbint.h
+index 4ef13d2f..d8293259 100644
+--- a/src/Xxcbint.h
++++ b/src/Xxcbint.h
+@@ -27,6 +27,7 @@ typedef struct _X11XCBPrivate {
+ PendingRequest *pending_requests;
+ PendingRequest *pending_requests_tail;
+ xcb_generic_event_t *next_event;
++ void *next_response;
+ char *real_bufmax;
+ char *reply_data;
+ int reply_length;
+diff --git a/src/xcb_io.c b/src/xcb_io.c
+index 6a12d150..bc76b69f 100644
+--- a/src/xcb_io.c
++++ b/src/xcb_io.c
+@@ -274,6 +274,7 @@ static xcb_generic_reply_t *poll_for_response(Display *dpy)
+ {
+ void *response;
+ xcb_generic_error_t *error;
++ xcb_generic_reply_t *event;
+ PendingRequest *req;
+ while(!(response = poll_for_event(dpy, False)) &&
+ (req = dpy->xcb->pending_requests) &&
+@@ -281,14 +282,37 @@ static xcb_generic_reply_t *poll_for_response(Display *dpy)
+ {
+ uint64_t request;
+
+- if(!xcb_poll_for_reply64(dpy->xcb->connection, req->sequence,
+- &response, &error)) {
++ /* xcb_poll_for_reply64 could not set error */
++ error = NULL;
++
++ /* return next pending response relative to req */
++ if(dpy->xcb->next_response)
++ {
++ response = dpy->xcb->next_response;
++ dpy->xcb->next_response = NULL;
++ if (((xcb_generic_reply_t*)response)->response_type == X_Error)
++ {
++ error = response;
++ response = NULL;
++ }
++ }
++ else if (!xcb_poll_for_reply64(dpy->xcb->connection, req->sequence,
++ &response, &error)) {
+ /* xcb_poll_for_reply64 may have read events even if
+ * there is no reply. */
+ response = poll_for_event(dpy, True);
+ break;
+ }
+
++ /* xcb_poll_for_reply64 may have read events */
++ event = poll_for_event(dpy, True);
++ if(event)
++ {
++ dpy->xcb->next_response = error ? error : response;
++ response = event;
++ break;
++ }
++
+ request = X_DPY_GET_REQUEST(dpy);
+ if(XLIB_SEQUENCE_COMPARE(req->sequence, >, request))
+ {
+--
+2.28.0
+
diff --git a/PKGBUILD b/PKGBUILD
index 23fc9d84e824..bd8d19edb607 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -16,9 +16,11 @@ provides=("libx11=${pkgver}")
conflicts=("libx11=${pkgver}")
license=('custom:XFREE86')
source=(${url}/releases/individual/lib/libX11-${pkgver}.tar.bz2{,.sig}
+ 0001-Fix-poll_for_response-race-condition.patch
threadsafe.patch)
sha512sums=('2cb4e215c1e3ccb327e02586844f8c426068536a0f472a39f12191feace607f61a6a08586f03758248199678c2f6897a984b0f1222bc0d68fd2e02702f4ce0bf'
'SKIP'
+ '8e45cf24ee3eaa735d79cfe768b87917be86ada8ae8688f44e1d914c52ac39be9815986432893d73b5c931ac2dd9a849d47bf2b2063b440f57a67c7d9ca5cc1f'
'625e747ddbbd6d84d9198199ecb9d93aad4e39c2b20b618bb2cc283c4c5aa3dd83bc80d45b002b612ffff2c70bf8d7cf1d07152097221b0c144a6cc06e0f5d63')
validpgpkeys=('4A193C06D35E7C670FA4EF0BA2FB9E081F2D130E') # Alan Coopersmith <alanc@freedesktop.org>
validpgpkeys+=('C41C985FDCF1E5364576638B687393EE37D128F8') # Matthieu Herrb <matthieu.herrb@laas.fr>
@@ -27,6 +29,7 @@ validpgpkeys+=('995ED5C8A6138EB0961F18474C09DD83CAAA50B2') # Adam Jackson <ajax@
prepare() {
cd "libX11-${pkgver}"
+ patch -Np1 <../0001-Fix-poll_for_response-race-condition.patch
patch -Np1 <../threadsafe.patch
}