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-05-23 11:08:17 +1000
commitd7a2df0a7499864cb005b098b79c1bdf884f6600 (patch)
treeae09c16354379474d45a5e5a7a167c70cace95ae
parentd3a3ee7a0e5cbd3fcaba77d2d5664e1524eda11c (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>
-rw-r--r--Xi/exevents.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 02530bdee..b0bc47e6d 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();
}
/**