summary refs log tree commit diff
path: root/gnu/packages/patches/icecat-CVE-2015-4473-partial.patch
blob: 184a8c5092d09ea43296bc8fdc0fa062d2f56c29 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
Backported to icecat-31.8 from the upstream esr38 branch.

From 1a7eac06fab3b8ffca09936498887f99e233bcba Mon Sep 17 00:00:00 2001
From: Randell Jesup <rjesup@jesup.org>
Date: Thu, 9 Jul 2015 20:18:34 -0400
Subject: [PATCH] Bug 1178890 - Update timer arrays after sleep to account for
 time sleeping. r=bwc, r=froydnj, a=sledru

--- icecat-31.8.0/xpcom/threads/TimerThread.cpp.orig	1969-12-31 19:00:00.000000000 -0500
+++ icecat-31.8.0/xpcom/threads/TimerThread.cpp	2015-08-12 16:38:11.789371171 -0400
@@ -28,7 +28,8 @@
   mShutdown(false),
   mWaiting(false),
   mNotified(false),
-  mSleeping(false)
+  mSleeping(false),
+  mLastTimerEventLoopRun(TimeStamp::Now())
 {
 }
 
@@ -222,6 +223,7 @@
     } else {
       waitFor = PR_INTERVAL_NO_TIMEOUT;
       TimeStamp now = TimeStamp::Now();
+      mLastTimerEventLoopRun = now;
       nsTimerImpl *timer = nullptr;
 
       if (!mTimers.IsEmpty()) {
@@ -411,6 +413,7 @@
 // This function must be called from within a lock
 int32_t TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
 {
+  mMonitor.AssertCurrentThreadOwns();
   if (mShutdown)
     return -1;
 
@@ -434,6 +437,7 @@
 
 bool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer)
 {
+  mMonitor.AssertCurrentThreadOwns();
   if (!mTimers.RemoveElement(aTimer))
     return false;
 
@@ -443,6 +447,10 @@
 
 void TimerThread::ReleaseTimerInternal(nsTimerImpl *aTimer)
 {
+  if (!mShutdown) {
+    // copied to a local array before releasing in shutdown
+    mMonitor.AssertCurrentThreadOwns();
+  }
   // Order is crucial here -- see nsTimerImpl::Release.
   aTimer->mArmed = false;
   NS_RELEASE(aTimer);
@@ -450,21 +458,39 @@
 
 void TimerThread::DoBeforeSleep()
 {
+  // Mainthread
+  MonitorAutoLock lock(mMonitor);
+  mLastTimerEventLoopRun = TimeStamp::Now();
   mSleeping = true;
 }
 
+// Note: wake may be notified without preceding sleep notification
 void TimerThread::DoAfterSleep()
 {
-  mSleeping = true; // wake may be notified without preceding sleep notification
+  // Mainthread
+  TimeStamp now = TimeStamp::Now();
+
+  MonitorAutoLock lock(mMonitor);
+
+  // an over-estimate of time slept, usually small
+  TimeDuration slept = now - mLastTimerEventLoopRun;
+
+  // Adjust all old timers to expire roughly similar times in the future
+  // compared to when we went to sleep, by adding the time we slept to the
+  // target time. It's slightly possible a few will end up slightly in the
+  // past and fire immediately, but ordering should be preserved.  All
+  // timers retain the exact same order (and relative times) as before
+  // going to sleep.
   for (uint32_t i = 0; i < mTimers.Length(); i ++) {
     nsTimerImpl *timer = mTimers[i];
-    // get and set the delay to cause its timeout to be recomputed
-    uint32_t delay;
-    timer->GetDelay(&delay);
-    timer->SetDelay(delay);
+    timer->mTimeout += slept;
   }
-
   mSleeping = false;
+  mLastTimerEventLoopRun = now;
+
+  // Wake up the timer thread to process the updated array
+  mNotified = true;
+  mMonitor.Notify();
 }
 
 
--- icecat-31.8.0/xpcom/threads/TimerThread.h.orig	1969-12-31 19:00:00.000000000 -0500
+++ icecat-31.8.0/xpcom/threads/TimerThread.h	2015-08-12 16:38:38.542408062 -0400
@@ -59,7 +59,7 @@
   mozilla::Atomic<bool> mInitInProgress;
   bool    mInitialized;
 
-  // These two internal helper methods must be called while mLock is held.
+  // These two internal helper methods must be called while mMonitor is held.
   // AddTimerInternal returns the position where the timer was added in the
   // list, or -1 if it failed.
   int32_t AddTimerInternal(nsTimerImpl *aTimer);
@@ -73,6 +73,7 @@
   bool mWaiting;
   bool mNotified;
   bool mSleeping;
+  TimeStamp mLastTimerEventLoopRun;
 
   nsTArray<nsTimerImpl*> mTimers;
 };