Closed Bug 1464565 Opened 7 years ago Closed 7 years ago

WebWorkers + postMessage can be used for ~5us resolution timing

Categories

(Core :: Security, enhancement)

60 Branch
enhancement
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 1432429

People

(Reporter: spinda, Unassigned)

Details

(Keywords: reporter-external)

Attachments

(3 files)

Attached file demo.html
VULNERABILITY DETAILS In the absence of SharedArrayBuffers, it is still possible to combine WebWorkers and postMessage to measure timing at a ~5us resolution (vs the 2ms exposed via performance.now since Firefox 60). We set up a Web Worker which continually increments a local counter from 0 and sends each new value to its parent via postMessage. An empty for-loop is run for 1,250 iterations between increments to throttle the number of messages the worker emits; otherwise, the event loop seems to become too clogged up with handling them and the browser hangs. If the parent has an active event handler attached to the window object's "message" event, messages sent to it via postMessage are queued for delivery. However, if there is no event handler registered, messages are simply discarded. Given this, our setup yields a shared counter increasing concurrently with the parent script's execution. To read a timestamp value in the parent script, we attach a handler to the message event to "catch" a WebWorker message in-flight. As previous messages would have been discarded with no message event handler to receive them, this is guaranteed to be the latest message received from the WebWorker. Then we immediately detach the handler so that further messages are discarded again. Extracting the counter value from the received message gives us a timestamp. In our testing, each postMessage "tick" corresponds to ~5us. VERSION Firefox Version: 60.0.1 (64-bit) stable Operating System: Windows 10 Pro Version 1709 (OS Build 16299.371) REPRODUCTION CASE `demo.html` computes time deltas for 1-second intervals using the method described above and compares them with time measurements from performance.now.
Flags: sec-bounty?
Thanks for your report - I wanted to acknowledge it but it's Memorial Day weekend in the US so we will look at this in more depth mid-week.
Group: core-security → dom-core-security
Chrome's behavior is interesting -- the performance.now() column is doubling. for me roughly 1.5s, 3.5, 7.4, 15.6, 39.8s (and then the slow script killer dialog). The ms/tick is fairly consistent at .023 - .027 on my machine. With Firefox on the same machine I'm getting a fairly consistent time in the performance.now() column. Ignoring the first count which was roughly double, 1000-1008 ms between measurements. The ms/tick was less consistent, ranging from .013 - .039.
Using postMessage() to construct a timer was described in the 'Fantastic Timers and Where to Find Them' paper and fixes are part of the larger "FuzzyFox" work.
Group: dom-core-security
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → DUPLICATE
Flags: sec-bounty? → sec-bounty-
(In reply to Daniel Veditz [:dveditz] from comment #2) > Chrome's behavior is interesting -- the performance.now() column is > doubling. for me roughly 1.5s, 3.5, 7.4, 15.6, 39.8s (and then the slow > script killer dialog). The ms/tick is fairly consistent at .023 - .027 on my > machine. > > With Firefox on the same machine I'm getting a fairly consistent time in the > performance.now() column. Ignoring the first count which was roughly double, > 1000-1008 ms between measurements. The ms/tick was less consistent, ranging > from .013 - .039. Interesting. This doesn't match my testing. I've attached sample results from Chrome and Firefox to the bug. Maybe the default "1250" message-delay value in the demo file is too low for your test system? (In reply to Daniel Veditz [:dveditz] from comment #3) > Using postMessage() to construct a timer was described in the 'Fantastic > Timers and Where to Find Them' paper and fixes are part of the larger > "FuzzyFox" work. I believe this is distinct from the techniques in the 'Fantastic Timers' paper in that it takes advantage of the behavior of postMessage dropping messages when the destination does not have 'message' event listener registered. This allows bypassing the round-trip through the message loop to request a current timestamp value. Instead, it's retrieved right away from the latest message pending in the event dispatcher (by attaching a 'message' listener).
Flags: needinfo?(dveditz)
Flags: needinfo?(dveditz) → needinfo?(luke)
I'm not sure what question specifically to answer. The Fantastic Timers paper showed resolutions up to 5us, so the presence of high-res implicit timers that require something like FuzzyFox to fix is already known, even if the technique here is new. I assume FuzzyFox would fix this new technique as well?
Flags: needinfo?(luke)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: