summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven McDonald <steven@steven-mcdonald.id.au>2014-05-18 13:42:08 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2014-06-27 09:47:59 +1000
commit2abbf56493bb8636ae1ef6de2cbb412ac79c717f (patch)
treecf1ddab4311924c5f4de4e226ee494810c227e9c
parent2ceb44827f86d9f5f995448c3cf603ee9459fef3 (diff)
Xi: block SIGIOs while copying device classes around
I've been seeing sporadic (anywhere from once every few days to 3-4 times a day) crashes and freezes in X. The problematic behaviour isn't always the same, but I chose a particular incident to debug, and found that X was segfaulting in updateMotionHistory, on line 575 of dix/getevents.c. After some further investigation, I found that the bug was being triggered when a SIGIO was received in DeepCopyPointerClasses, between the AllocValuatorClass call (line 540) and updating the to->valuator pointer (line 545). AllocValuatorClass calls realloc() on to->valuator, so between these lines, it's not guaranteed to point to allocated memory. It seems the SIGIO handler is calling updateMotionHistory, which is reading the memory pointed to by to->valuator and getting a wrong value for last_motion, which updates buff to point to wildly the wrong place and thus generates a segfault when a memcpy() is done into buff. I am attaching a patch which I've been running on that machine for the past three days, and haven't yet observed any more crashing or freezing behaviour. The patch simply calls OsBlockSIGIO while DeepCopyDeviceClasses is in progress, as the state of the X server's device data structures is not guaranteed to be in a consistent state during that time. Debian bug#744303 <https://bugs.debian.org/744303> Signed-off-by: Julien Cristau <jcristau@debian.org> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> (cherry picked from commit d7a2df0a7499864cb005b098b79c1bdf884f6600)
-rw-r--r--Xi/exevents.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index ad0265093..01bdea6df 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -661,6 +661,8 @@ void
DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to,
DeviceChangedEvent *dce)
{
+ OsBlockSIGIO();
+
/* generic feedback classes, not tied to pointer and/or keyboard */
DeepCopyFeedbackClasses(from, to);
@@ -668,6 +670,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to,
DeepCopyKeyboardClasses(from, to);
if ((dce->flags & DEVCHANGE_POINTER_EVENT))
DeepCopyPointerClasses(from, to);
+
+ OsReleaseSIGIO();
}
/**