5

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.)?

1

1 Answer 1

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:

#include <pthread.h>

volatile unsigned long counter = 0;

static void *counter_thread(void *arg)
{
    while (1)
        counter++;
}

static void __attribute__((constructor)) init_counter(void)
{
    pthread_id id;
    pthread_create(&id, NULL, counter_thread, NULL);
}

unsigned long get_counter(void)
{
    return counter;
}

Loading this sample library starts a new thread that rapidly increments a variable. It exports a function get_counter() that returns the current value of that variable at the time it is called. The counter is incremented at a very high and fairly steady rate, providing a high-resolution timer similar to RDTSC.

As a result, there is no way to hide precise timing information from machine code executing on the CPU. It is sometimes 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. Note that this is not always sufficient, as a number of other techniques exist which can be used to implement high-resolution timers in JavaScript. Some of these additional techniques have been mitigated, but not all. Disabling JIT can drastically reduce timing attacks in JavaScript.

6
  • 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
    Commented Jan 9, 2018 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
    Commented Jan 9, 2018 at 17:07
  • @Drux, the first would be better asked on a programming site, the second on SuperUser.
    – Mark
    Commented Jan 9, 2018 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
    Commented Jan 10, 2018 at 6:57
  • 1
    gruss.cc/files/fantastictimers.pdf Commented Jun 26, 2018 at 7:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .