diff -u xorg-server-1.16.2.901/debian/changelog xorg-server-1.16.2.901/debian/changelog --- xorg-server-1.16.2.901/debian/changelog +++ xorg-server-1.16.2.901/debian/changelog @@ -1,3 +1,10 @@ +xorg-server (2:1.16.2.901-1ubuntu5) vivid; urgency=low + + * debian/patches/os-fix-timer-race-conditions.patch: fix a race condition + triggered when using certain touchpads with Nvidia GPUs (LP: #1220426) + + -- Matthew Haughton Sun, 22 Feb 2015 18:09:26 -0500 + xorg-server (2:1.16.2.901-1ubuntu4) vivid; urgency=medium * SECURITY UPDATE: information leak and denial of service in diff -u xorg-server-1.16.2.901/debian/patches/series xorg-server-1.16.2.901/debian/patches/series --- xorg-server-1.16.2.901/debian/patches/series +++ xorg-server-1.16.2.901/debian/patches/series @@ -36,6 +36,9 @@ # Probably is just papering over issue; needs further analysis ## upstream patches +os-fix-timer-race-conditions.patch +# https://bugs.freedesktop.org/show_bug.cgi?id=86288 +# cherry-pick fe4c774c572e3f55a7417f0ca336ae1479a966ad from upstream # hybrid graphics fixes 228_autobind_gpu.patch only in patch2: unchanged: --- xorg-server-1.16.2.901.orig/debian/patches/os-fix-timer-race-conditions.patch +++ xorg-server-1.16.2.901/debian/patches/os-fix-timer-race-conditions.patch @@ -0,0 +1,152 @@ +## Subject: os: Fix timer race conditions +## Origin: http://cgit.freedesktop.org/xorg/xserver/commit/?id=fe4c774c572e3f55a7417f0ca336ae1479a966ad +## Bug: https://bugs.freedesktop.org/show_bug.cgi?id=86288 +## Applied-Upstream: 1.17.0 +From fe4c774c572e3f55a7417f0ca336ae1479a966ad Mon Sep 17 00:00:00 2001 +From: Nikhil Mahale +Date: Sat, 24 Jan 2015 17:06:59 -0800 +Subject: os: Fix timer race conditions + +Fixing following kind of race-conditions - + + WaitForSomething() + | + ----> // timers -> timer-1 -> timer-2 -> null + while (timers && (int) (timers->expires - now) <= 0) + // prototype - DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) + DoTimer(timers, now, &timers) + | + | + ----> OsBlockSignals(); .... OS Signal comes just before blocking it, + .... timer-1 handler gets called. + // timer-1 gets served and scheduled again; + // timers -> timer-2 -> timer-1 -> null + .... + *prev = timer->next; + timer->next = NULL; // timers -> null + // timers list gets corrupted here and timer-2 gets removed from list. + +Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=86288 +Signed-off-by: Nikhil Mahale +Reviewed-by: Julien Cristau + +v2: Apply warning fixes from Keith Packard + +Reviewed-by: Aaron Plattner +Signed-off-by: Aaron Plattner +Signed-off-by: Keith Packard + +diff --git a/os/WaitFor.c b/os/WaitFor.c +index 86d96c8..431f1a6 100644 +--- a/os/WaitFor.c ++++ b/os/WaitFor.c +@@ -121,9 +121,9 @@ struct _OsTimerRec { + void *arg; + }; + +-static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); ++static void DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev); + static void CheckAllTimers(void); +-static OsTimerPtr timers = NULL; ++static volatile OsTimerPtr timers = NULL; + + /***************** + * WaitForSomething: +@@ -263,11 +263,14 @@ WaitForSomething(int *pClientsReady) + if ((int) (timers->expires - now) <= 0) + expired = 1; + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); ++ if (expired) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); + +- if (expired) + return 0; ++ } + } + } + else { +@@ -281,11 +284,14 @@ WaitForSomething(int *pClientsReady) + if ((int) (timers->expires - now) <= 0) + expired = 1; + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); ++ if (expired) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); + +- if (expired) + return 0; ++ } + } + } + if (someReady) +@@ -401,24 +407,25 @@ CheckAllTimers(void) + } + + static void +-DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) ++DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev) + { + CARD32 newTime; + + OsBlockSignals(); + *prev = timer->next; + timer->next = NULL; ++ OsReleaseSignals(); ++ + newTime = (*timer->callback) (timer, now, timer->arg); + if (newTime) + TimerSet(timer, 0, newTime, timer->callback, timer->arg); +- OsReleaseSignals(); + } + + OsTimerPtr + TimerSet(OsTimerPtr timer, int flags, CARD32 millis, + OsTimerCallback func, void *arg) + { +- register OsTimerPtr *prev; ++ volatile OsTimerPtr *prev; + CARD32 now = GetTimeInMillis(); + + if (!timer) { +@@ -470,7 +477,7 @@ Bool + TimerForce(OsTimerPtr timer) + { + int rc = FALSE; +- OsTimerPtr *prev; ++ volatile OsTimerPtr *prev; + + OsBlockSignals(); + for (prev = &timers; *prev; prev = &(*prev)->next) { +@@ -487,7 +494,7 @@ TimerForce(OsTimerPtr timer) + void + TimerCancel(OsTimerPtr timer) + { +- OsTimerPtr *prev; ++ volatile OsTimerPtr *prev; + + if (!timer) + return; +@@ -515,8 +522,12 @@ TimerCheck(void) + { + CARD32 now = GetTimeInMillis(); + +- while (timers && (int) (timers->expires - now) <= 0) +- DoTimer(timers, now, &timers); ++ if (timers && (int) (timers->expires - now) <= 0) { ++ OsBlockSignals(); ++ while (timers && (int) (timers->expires - now) <= 0) ++ DoTimer(timers, now, &timers); ++ OsReleaseSignals(); ++ } + } + + void