Package: rxvt Version: 1:2.7.10-7 Severity: normal Tags: patch Dear Maintainer,
Here are two patches, see the git commit message for more details. rxvt is incorrectly using sizeof to calculate the format for XChangeProperty, getting 64 on a 64 bit system, when 8, 16, 32 are the only options. This results in rxvt terminating when it receives a request for a TIMESTAMP on the primary selection. If completely obscured and something requests a draw, rxvt correctly detects that there's no point in drawing, but needs to clear want_refresh to avoid sleeping 5ms and trying again. Both changes are effectively one line code changes. -- System Information: Debian Release: 9.5 APT prefers stable APT policy: (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.18.0+ (SMP w/4 CPU cores) Locale: LANG=C, LC_CTYPE=en_US.ISO-8859-15 (charmap=ISO-8859-15), LANGUAGE=C (charmap=ISO-8859-15) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages rxvt depends on: ii libc6 2.24-11+deb9u3 ii libx11-6 2:1.6.4-3 ii libxpm4 1:3.5.12-1 rxvt recommends no packages. rxvt suggests no packages. -- no debconf information
>From f03a0f43a92bb06acefe29a62b50001218f4c45a Mon Sep 17 00:00:00 2001 From: David Fries <da...@fries.net> Date: Sat, 29 Sep 2018 22:26:43 -0500 Subject: [PATCH 1/3] fix XA_TIMESTAMP XChangeProperty format value If rxvt owns the primary selection buffer and another program queries the TIMESTAMP as the target to XConvertSelection, rxvt will exit with the following X error (after disabling rxvt's error handler to let the built in handler decode it). X Error of failed request: BadValue (integer parameter out of range for operation) Major opcode of failed request: 18 (X_ChangeProperty) Value in failed request: 0x40 Serial number of failed request: 232 Current serial number in output stream: 233 The failed value is 0x40 which is 64, which is (8 * sizeof(Time)) on a 64 bit system, but the man page to XChangeProperty property states, "Possible values are 8, 16, and 32." This is an integer, set the value to 32. source code to a simple program to request the TIMESTAMP from the primary selection owner can be found here, https://gitlab.com/dfries64/xconvertselection_timestamp --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 5f3ed75..dd5def7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -3647,7 +3647,7 @@ rxvt_selection_send(rxvt_t *r, const XSelectionRequestEvent *rq) /* TODO: Handle MULTIPLE */ } else if (rq->target == r->h->xa[XA_TIMESTAMP] && r->selection.text) { XChangeProperty(r->Xdisplay, rq->requestor, rq->property, XA_INTEGER, - (8 * sizeof(Time)), PropModeReplace, + 32, PropModeReplace, (unsigned char *)&r->h->selection_time, 1); ev.property = rq->property; } else if (rq->target == XA_STRING -- 2.11.0 >From 1f5325b8c546a859d4f00a02292656187e19f8e4 Mon Sep 17 00:00:00 2001 From: David Fries <da...@fries.net> Date: Thu, 27 Sep 2018 22:47:51 -0500 Subject: [PATCH 2/3] rxvt eats cpu when needing to draw while obscured If the window is completely obscured and needs to draw then rxvt_scr_refresh will return immediately instead of drawing, (no need to draw what can't be seen), but if want_refresh is true, it will do a 5ms select timeout and try again forever. The solution is to clear want_refresh before returning from rxvt_scr_refresh. To reproduce run `strace rxvt`, then `top` in that rxvt window (or anything with a delay that will trigger a draw, `sleep 5` works), completely cover the rxvt window with another and wait for the timeout. strace will show a steady stream of select (which times out), and recvmsg. --- src/screen.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index dd5def7..d637930 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2046,8 +2046,15 @@ rxvt_scr_refresh(rxvt_t *r, unsigned char refresh_type) int (*draw_string_func) () = draw_string; int (*draw_image_string_func) () = draw_image_string; - if (refresh_type == NO_REFRESH || !r->TermWin.mapped) + if (refresh_type == NO_REFRESH || !r->TermWin.mapped) { + /* If the window is completely obscured (NO_REFRESH) we really don't + * want to refresh, that is why we are returning instead, but first we + * must say mark the flag don't refresh. A similar argument works for + * !mapped. + */ + h->want_refresh = 0; return; + } /* * A: set up vars -- 2.11.0 >From f12ebf710079400f44e9b16fc0bf7c2a9635fd1c Mon Sep 17 00:00:00 2001 From: David Fries <da...@fries.net> Date: Wed, 26 Sep 2018 21:55:47 -0500 Subject: [PATCH 3/3] change long with hang, hang, X error termination, wasting cpu --- debian/changelog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/debian/changelog b/debian/changelog index 35341f9..27333ac 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +rxvt (1:2.7.10-7nohang) unstable; urgency=medium + + * Fixed rxvt hang on exit, seteuid() gets a mutex, is interrupted with + SIGCHLD signal, calls the same exit path and seteuid() blocks waiting for + mutex + * Fixed rxvt hang on exit, malloc gets a mutex, is interrupted with + SIGCHLD signal, rxvt_clean_exit calls XDestroyIC(), and free() blocks + waiting for mutex + * fix termination due to X error, a XA_TIMESTAMP query called XChangeProperty + with 64 instead of 32 + * fix looping with a 5ms timeout when needing to draw while completely + obscured + + -- David Fries <da...@fries.net> Wed, 26 Sep 2018 21:55:35 -0500 + rxvt (1:2.7.10-7) unstable; urgency=medium * Fixed rxvt-ml cjk builds to use updated configure params. -- 2.11.0