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.