From a32b7f7c4e4e31669e0787e6321d74e4db71e514 Mon Sep 17 00:00:00 2001 From: Tom Ritter Date: Tue, 20 Feb 2018 12:18:30 -0600 Subject: Bug 1430173 - Reduce the precision of all explicit clocks to 2ms. r=baku, a=RyanVM Backport to ESR where we don't have the ResistFingerprinting component. MozReview-Commit-ID: 9bjycHjR3SF --HG-- extra : transplant_source : %EA%03%21%0A%E9%3F%8E%CD%7C%D79f%96%85%96%00%5D%7F%95X --- dom/base/File.cpp | 3 ++- dom/base/MultipartBlobImpl.cpp | 4 ++-- dom/base/TimerClamping.cpp | 35 +++++++++++++++++++++++++++++++++++ dom/base/TimerClamping.h | 22 ++++++++++++++++++++++ dom/base/moz.build | 2 ++ dom/console/Console.cpp | 3 ++- dom/events/Event.cpp | 7 +++++++ dom/events/Event.h | 1 + dom/media/DOMMediaStream.cpp | 5 +++-- dom/media/webaudio/AudioContext.cpp | 3 ++- dom/performance/Performance.cpp | 5 +++-- dom/performance/PerformanceTiming.cpp | 22 +++++++++++----------- dom/performance/PerformanceTiming.h | 25 +++++++++++++------------ js/src/jsdate.cpp | 5 ++++- 14 files changed, 109 insertions(+), 33 deletions(-) mode change 100644 => 100755 dom/base/File.cpp mode change 100644 => 100755 dom/base/MultipartBlobImpl.cpp create mode 100755 dom/base/TimerClamping.cpp create mode 100755 dom/base/TimerClamping.h mode change 100644 => 100755 dom/base/moz.build mode change 100644 => 100755 dom/console/Console.cpp mode change 100644 => 100755 dom/events/Event.cpp mode change 100644 => 100755 dom/events/Event.h mode change 100644 => 100755 dom/media/DOMMediaStream.cpp mode change 100644 => 100755 dom/media/webaudio/AudioContext.cpp mode change 100644 => 100755 dom/performance/Performance.cpp mode change 100644 => 100755 dom/performance/PerformanceTiming.cpp mode change 100644 => 100755 dom/performance/PerformanceTiming.h mode change 100644 => 100755 js/src/jsdate.cpp diff --git a/dom/base/File.cpp b/dom/base/File.cpp old mode 100644 new mode 100755 index 46b37b976..8602a3064 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -29,6 +29,7 @@ #include "nsStringStream.h" #include "nsJSUtils.h" #include "nsPrintfCString.h" +#include "mozilla/TimerClamping.h" #include "mozilla/SHA1.h" #include "mozilla/CheckedInt.h" #include "mozilla/Preferences.h" @@ -727,7 +728,7 @@ BlobImplBase::GetLastModified(ErrorResult& aRv) mLastModificationDate = PR_Now(); } - return mLastModificationDate / PR_USEC_PER_MSEC; + return TimerClamping::ReduceUsTimeValue(mLastModificationDate) / PR_USEC_PER_MSEC; } void diff --git a/dom/base/MultipartBlobImpl.cpp b/dom/base/MultipartBlobImpl.cpp old mode 100644 new mode 100755 index ba26d07f9..03bb62add --- a/dom/base/MultipartBlobImpl.cpp +++ b/dom/base/MultipartBlobImpl.cpp @@ -17,6 +17,7 @@ #include "nsContentUtils.h" #include "nsIScriptError.h" #include "nsIXPConnect.h" +#include "mozilla/TimerClamping.h" #include using namespace mozilla; @@ -270,8 +271,7 @@ MultipartBlobImpl::SetLengthAndModifiedDate(ErrorResult& aRv) // var x = new Date(); var f = new File(...); // x.getTime() < f.dateModified.getTime() // could fail. - mLastModificationDate = - lastModifiedSet ? lastModified * PR_USEC_PER_MSEC : JS_Now(); + mLastModificationDate = TimerClamping::ReduceUsTimeValue(lastModifiedSet ? lastModified * PR_USEC_PER_MSEC : JS_Now()); } } diff --git a/dom/base/TimerClamping.cpp b/dom/base/TimerClamping.cpp new file mode 100755 index 000000000..70639686b --- /dev/null +++ b/dom/base/TimerClamping.cpp @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "TimerClamping.h" + +namespace mozilla { + +/* static */ +double +TimerClamping::ReduceSTimeValue(double aTime) +{ + static const double maxResolutionS = .002; + return floor(aTime / maxResolutionS) * maxResolutionS; +} + +/* static */ +double +TimerClamping::ReduceMsTimeValue(double aTime) +{ + static const double maxResolutionMs = 2; + return floor(aTime / maxResolutionMs) * maxResolutionMs; +} + +/* static */ +double +TimerClamping::ReduceUsTimeValue(double aTime) +{ + static const double maxResolutionUs = 2000; + return floor(aTime / maxResolutionUs) * maxResolutionUs; +} + +} \ No newline at end of file diff --git a/dom/base/TimerClamping.h b/dom/base/TimerClamping.h new file mode 100755 index 000000000..2ffd6add5 --- /dev/null +++ b/dom/base/TimerClamping.h @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef TimerClamping_h___ +#define TimerClamping_h___ + +namespace mozilla { + +class TimerClamping +{ +public: + static double ReduceSTimeValue(double aTime); + static double ReduceMsTimeValue(double aTime); + static double ReduceUsTimeValue(double aTime); +}; + +} + +#endif /* TimerClamping_h___ */ \ No newline at end of file diff --git a/dom/base/moz.build b/dom/base/moz.build old mode 100644 new mode 100755 index 686d76e73..0fb345d22 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -143,6 +143,7 @@ EXPORTS.mozilla += [ 'CORSMode.h', 'FeedWriterEnabled.h', 'TextInputProcessor.h', + 'TimerClamping.h', 'UseCounter.h', ] @@ -363,6 +364,7 @@ UNIFIED_SOURCES += [ 'TextInputProcessor.cpp', 'ThirdPartyUtil.cpp', 'Timeout.cpp', + 'TimerClamping.cpp', 'TreeWalker.cpp', 'WebKitCSSMatrix.cpp', 'WebSocket.cpp', diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp old mode 100644 new mode 100755 index 9ede26501..79e3eadc5 --- a/dom/console/Console.cpp +++ b/dom/console/Console.cpp @@ -30,6 +30,7 @@ #include "nsContentUtils.h" #include "nsDocShell.h" #include "nsProxyRelease.h" +#include "mozilla/TimerClamping.h" #include "mozilla/ConsoleTimelineMarker.h" #include "mozilla/TimestampTimelineMarker.h" @@ -1338,7 +1339,7 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName, TimeDuration duration = mozilla::TimeStamp::Now() - workerPrivate->NowBaseTimeStamp(); - monotonicTimer = duration.ToMilliseconds(); + monotonicTimer = TimerClamping::ReduceMsTimeValue(duration.ToMilliseconds()); } } diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp old mode 100644 new mode 100755 index a85a0d66b..2af34136e --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -32,6 +32,7 @@ #include "nsJSEnvironment.h" #include "nsLayoutUtils.h" #include "nsPIWindowRoot.h" +#include "mozilla/TimerClamping.h" #include "WorkerPrivate.h" namespace mozilla { @@ -1084,6 +1085,12 @@ Event::DefaultPrevented(JSContext* aCx) const double Event::TimeStamp() const +{ + return TimerClamping::ReduceMsTimeValue(TimeStampImpl()); +} + +double +Event::TimeStampImpl() const { if (!sReturnHighResTimeStamp) { return static_cast(mEvent->mTime); diff --git a/dom/events/Event.h b/dom/events/Event.h old mode 100644 new mode 100755 index 4ac6a68d5..c28226e8a --- a/dom/events/Event.h +++ b/dom/events/Event.h @@ -62,6 +62,7 @@ private: void ConstructorInit(EventTarget* aOwner, nsPresContext* aPresContext, WidgetEvent* aEvent); + double TimeStampImpl() const; public: static Event* FromSupports(nsISupports* aSupports) diff --git a/dom/media/DOMMediaStream.cpp b/dom/media/DOMMediaStream.cpp old mode 100644 new mode 100755 index 6794ee32f..c1d451035 --- a/dom/media/DOMMediaStream.cpp +++ b/dom/media/DOMMediaStream.cpp @@ -9,6 +9,7 @@ #include "nsIScriptError.h" #include "nsIUUIDGenerator.h" #include "nsPIDOMWindow.h" +#include "mozilla/TimerClamping.h" #include "mozilla/dom/MediaStreamBinding.h" #include "mozilla/dom/MediaStreamTrackEvent.h" #include "mozilla/dom/LocalMediaStreamBinding.h" @@ -544,8 +545,8 @@ DOMMediaStream::CurrentTime() if (!mPlaybackStream) { return 0.0; } - return mPlaybackStream-> - StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime); + return TimerClamping::ReduceSTimeValue(mPlaybackStream-> + StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime)); } void diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp old mode 100644 new mode 100755 index a36eda621..85842c811 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -41,6 +41,7 @@ #include "nsNetUtil.h" #include "nsPIDOMWindow.h" #include "nsPrintfCString.h" +#include "mozilla/TimerClamping.h" #include "OscillatorNode.h" #include "PannerNode.h" #include "PeriodicWave.h" @@ -746,7 +747,7 @@ double AudioContext::CurrentTime() const { MediaStream* stream = Destination()->Stream(); - return stream->StreamTimeToSeconds(stream->GetCurrentTime()); + return TimerClamping::ReduceSTimeValue(stream->StreamTimeToSeconds(stream->GetCurrentTime())); } void diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp old mode 100644 new mode 100755 index 17273c55d..8dc239b05 --- a/dom/performance/Performance.cpp +++ b/dom/performance/Performance.cpp @@ -21,6 +21,7 @@ #include "mozilla/dom/PerformanceObserverBinding.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Preferences.h" +#include "mozilla/TimerClamping.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" @@ -228,9 +229,9 @@ Performance::ClearResourceTimings() DOMHighResTimeStamp Performance::RoundTime(double aTime) const { - // Round down to the nearest 20us, because if the timer is too accurate people + // Round down to the nearest 2ms, because if the timer is too accurate people // can do nasty timing attacks with it. - const double maxResolutionMs = 0.020; + const double maxResolutionMs = 2; return floor(aTime / maxResolutionMs) * maxResolutionMs; } diff --git a/dom/performance/PerformanceTiming.cpp b/dom/performance/PerformanceTiming.cpp old mode 100644 new mode 100755 index 4070b6a0f..97bbcb0ca --- a/dom/performance/PerformanceTiming.cpp +++ b/dom/performance/PerformanceTiming.cpp @@ -21,7 +21,7 @@ PerformanceTiming::PerformanceTiming(Performance* aPerformance, DOMHighResTimeStamp aZeroTime) : mPerformance(aPerformance), mFetchStart(0.0), - mZeroTime(aZeroTime), + mZeroTime(TimerClamping::ReduceMsTimeValue(aZeroTime)), mRedirectCount(0), mTimingAllowed(true), mAllRedirectsSameOrigin(true), @@ -117,7 +117,7 @@ PerformanceTiming::FetchStartHighRes() ? TimeStampToDOMHighRes(mAsyncOpen) : 0.0; } - return mFetchStart; + return TimerClamping::ReduceMsTimeValue(mFetchStart); } DOMTimeMilliSec @@ -203,7 +203,7 @@ PerformanceTiming::RedirectStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRedirectStart); + return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart); } DOMTimeMilliSec @@ -236,7 +236,7 @@ PerformanceTiming::RedirectEndHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRedirectEnd); + return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd); } DOMTimeMilliSec @@ -259,7 +259,7 @@ PerformanceTiming::DomainLookupStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart); + return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart); } DOMTimeMilliSec @@ -276,7 +276,7 @@ PerformanceTiming::DomainLookupEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes() - : TimeStampToDOMHighRes(mDomainLookupEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mDomainLookupEnd)); } DOMTimeMilliSec @@ -292,7 +292,7 @@ PerformanceTiming::ConnectStartHighRes() return mZeroTime; } return mConnectStart.IsNull() ? DomainLookupEndHighRes() - : TimeStampToDOMHighRes(mConnectStart); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectStart)); } DOMTimeMilliSec @@ -329,7 +329,7 @@ PerformanceTiming::ConnectEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null return mConnectEnd.IsNull() ? ConnectStartHighRes() - : TimeStampToDOMHighRes(mConnectEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectEnd)); } DOMTimeMilliSec @@ -344,7 +344,7 @@ PerformanceTiming::RequestStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRequestStart); + return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart); } DOMTimeMilliSec @@ -363,7 +363,7 @@ PerformanceTiming::ResponseStartHighRes() (!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) { mResponseStart = mCacheReadStart; } - return TimeStampToDOMHighResOrFetchStart(mResponseStart); + return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart); } DOMTimeMilliSec @@ -384,7 +384,7 @@ PerformanceTiming::ResponseEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null return mResponseEnd.IsNull() ? ResponseStartHighRes() - : TimeStampToDOMHighRes(mResponseEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mResponseEnd)); } DOMTimeMilliSec diff --git a/dom/performance/PerformanceTiming.h b/dom/performance/PerformanceTiming.h old mode 100644 new mode 100755 index 0bc73fd3f..edfac8d02 --- a/dom/performance/PerformanceTiming.h +++ b/dom/performance/PerformanceTiming.h @@ -10,6 +10,7 @@ #include "mozilla/Attributes.h" #include "nsContentUtils.h" #include "nsDOMNavigationTiming.h" +#include "mozilla/TimerClamping.h" #include "nsWrapperCache.h" #include "Performance.h" @@ -68,10 +69,10 @@ public: * page), if the given TimeStamp is valid. Otherwise, it will return * the FetchStart timing value. */ - inline DOMHighResTimeStamp TimeStampToDOMHighResOrFetchStart(TimeStamp aStamp) + inline DOMHighResTimeStamp TimeStampToReducedDOMHighResOrFetchStart(TimeStamp aStamp) { return (!aStamp.IsNull()) - ? TimeStampToDOMHighRes(aStamp) + ? TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(aStamp)) : FetchStartHighRes(); } @@ -119,7 +120,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetNavigationStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetNavigationStart()); } DOMTimeMilliSec UnloadEventStart() @@ -127,7 +128,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetUnloadEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventStart()); } DOMTimeMilliSec UnloadEventEnd() @@ -135,7 +136,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetUnloadEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventEnd()); } uint16_t GetRedirectCount() const; @@ -185,7 +186,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomLoading(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomLoading()); } DOMTimeMilliSec DomInteractive() const @@ -193,7 +194,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomInteractive(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomInteractive()); } DOMTimeMilliSec DomContentLoadedEventStart() const @@ -201,7 +202,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomContentLoadedEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventStart()); } DOMTimeMilliSec DomContentLoadedEventEnd() const @@ -209,7 +210,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomContentLoadedEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventEnd()); } DOMTimeMilliSec DomComplete() const @@ -217,7 +218,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomComplete(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomComplete()); } DOMTimeMilliSec LoadEventStart() const @@ -225,7 +226,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetLoadEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventStart()); } DOMTimeMilliSec LoadEventEnd() const @@ -233,7 +234,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetLoadEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventEnd()); } private: diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp old mode 100644 new mode 100755 index d73fb93d2..ccaeda2a3 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -1232,7 +1232,10 @@ date_parse(JSContext* cx, unsigned argc, Value* vp) static ClippedTime NowAsMillis() { - return TimeClip(static_cast(PRMJ_Now()) / PRMJ_USEC_PER_MSEC); + const double maxResolutionMs = 2; + double timestamp = static_cast(PRMJ_Now()) / PRMJ_USEC_PER_MSEC; + timestamp = floor(timestamp / maxResolutionMs) * maxResolutionMs; + return TimeClip(timestamp); } bool -- cgit v1.2.3