4

I have read that Firefox' current mitigation against Meltdown and Spectre (from 57.x) consists of the following:

  • The resolution of performance.now() will be reduced to 20µs.
  • The SharedArrayBuffer feature is being disabled by default.

Is it correct to assume that substantially reducing the amount of information obtainable from timing (such as reducing the resolution to 20µs is this case) is a very effective way for addressing the issue in the case of JavaScript runtimes, but that one would introduce lots of (far too many) unwanted side-effects when applying something like this "hammer" to the Linux kernel (hence the additional need for KPTI, etc.)?

3

The reason it is only applied to browsers is because there is no way to fully eliminate high-resolution timing information from code being natively executed. For example, the RDTSC instruction provides precise, sub-nanosecond resolution timing information to any process. While it is possible to disable this instruction by making it executable only by privileged code (by setting the CR4.TSD bit), much of userland relies on it. However even if you did successfully disable it without breakage, a timer of similar resolution could be jerry-rigged by incrementing a variable in a fast loop. Userspace code will always have nanosecond-precision timing information. Such a timer could be implemented easily:

register volatile unsigned long counter;

void counter_thread(void)
{
    while (1) counter++;
}

The counter_thread() function would be run in its own thread, and in another thread, the value of counter could be sampled at an arbitrary time. As the rate of the counter being incremented would be very high and fairly constant, it would provide a high-resolution timer similar to RDTSC.

As a result, there is no way to hide precise timing information from any process executing directly on the CPU. It is only possible in JavaScript because it is a managed, high-level language which does not have raw access to CPU instructions, and timing must go through dedicated APIs such as performance.now(), which can have its granularity adjusted by modifying the JavaScript engine.

  • 3
    Turns out, you can use a tight loop in JIT'd Javascript to get the timing you need for Spectre. It's only interpreted Javascript that can't use a timing loop to get around the lack of a high-resolution clock. – Mark Jan 9 '18 at 10:08
  • forest & @Mark +1 I do have two follow-up questions. (Please advise if you want me to post separate new questions on this site.) (1) Is performance.new() the central API for timing that all other abstractions in JavaScript rely upon, or is it just one out of many (perhaps one that was convenient for Firefox authors to update)? (2) Can I somehow disable JavaScript JIT compilation for Firefox? – Drux Jan 9 '18 at 17:07
  • @Drux, the first would be better asked on a programming site, the second on SuperUser. – Mark Jan 9 '18 at 19:14
  • 1
    @Drux It is the central API for high-resolution timing, but there are multiple ways to obtain this timing information. Timing attacks in browsers is still an open problem. As for disabling JIT in Firefox, you can do this by setting javascript.options.baselinejit to false. – forest Jan 10 '18 at 6:57
  • @forest Re-thx, great answer and comment. I may ask (yet another and this time separate) follow-up question on remaining exposures from "leaking" "too-precise" timing information when JIT is off. – Drux Jan 10 '18 at 7:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.