[tor-bugs] #21010 [Applications/Tor Browser Sandbox]: Disable RDTSC/RDTSCP to limit side-channel attacks

Tor Bug Tracker & Wiki blackhole at torproject.org
Sat Dec 17 08:11:40 UTC 2016


#21010: Disable RDTSC/RDTSCP to limit side-channel attacks
--------------------------------------------------+---------------------
     Reporter:  cypherpunks                       |      Owner:  yawning
         Type:  enhancement                       |     Status:  new
     Priority:  Medium                            |  Milestone:
    Component:  Applications/Tor Browser Sandbox  |    Version:
     Severity:  Normal                            |   Keywords:
Actual Points:                                    |  Parent ID:
       Points:                                    |   Reviewer:
      Sponsor:                                    |
--------------------------------------------------+---------------------
 //TL;DR If you don't use vDSO, you can disable the TSC instructions
 without causing segfaults.//

 Side-channel attacks like FLUSH+FLUSH, FLUSH+RELOAD, PRIME+PROBE, and
 EVICT+TIME can be used for covert information exfiltration, cross-process
 and cross-VM keylogging, breaking poor crypto implementations (especially
 JS-based crypto), and massively enhancing rowhammer attacks by enumerating
 the physical row layout and physical memory layout, improving a generic
 attack of 2 flips in 10 minutes to 30 flips per second on some hardware.
 These attacks all require a high-precision timestamp counter instruction
 to function, and don't involve making syscalls, so seccomp does not defend
 against them. They have the same keylogging effects which grsecurity's
 `/dev/ptmx` anti-side channel technique was designed to protect against,
 so it bad news.

 This is even worse for Tor Browser users, as in addition to limited
 keylogging abilities, it allows for extensive cross-process (the user
 doesn't need to be using the keyboard or mouse in the compromise Firefox
 process) biometric fingerprinting via keystroke dynamics in a way that's
 not practical using JavaScript's `performance.now()` or whatever it does.
 That function has a resolution in the hundreds of nanoseconds even with
 JIT enabled (and I hope your sandboxed browser will disable JIT), compared
 to `RDTSC` which tends to be sub-nanosecond, making it fast enough to be
 cross-process, and cross-VM (everything but cross-NUMA node). On the
 bright side, x86 CPUs allow making this instruction available to ring 0
 only via `CR4.TSD` (the timestamp disable bit in the 4th control
 register), and the Linux kernel exposes an interface to allow userland to
 toggle this on a per-process basis using `prctl()`.

 Example usage, in C:
 {{{
 #include <sys/prctl.h>
 #include <stdlib.h>
 #include <stdio.h>

 /* disable the TSC */
 if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV, 0, 0, 0) == -1)
     exit(1);

 /* enable the TSC */
 if (prctl(PR_SET_TSC, PR_SET_ENABLE, 0, 0, 0) == -1)
     exit(1);

 /* check the TSC state */
 int tsc;
 if (prctl(PR_GET_TSC, &tsc, 0, 0, 0) == -1)
     exit(1);

 printf("The TSC is %s for this process\n", tsc ? "enabled" : "disabled");
 }}}

 With this in mind, it should be important to consider disabling the TSC in
 Tor Browser using the sandbox, and using seccomp to prevent it from re-
 enabling it with `prctl()`. However, as a lot of people who have tried
 this have seen, many glibc processes instantly segfault when this is done.
 The reason this happens is that a few syscalls, namely `getcpu()`,
 `gettimeofday()`, `time()`, and `clock_gettime()` use the `RDTSC`
 instruction because, on x86, they are not a syscall, but a vDSO, meaning
 the syscalls take place entirely in userspace (though a small dynamically
 updating read-only bit of memory, called the VVAR, is created by the
 kernel for the vDSO to poll), without requiring a context switch at all,
 in order to improve performance. Unfortunately, some of those calls with
 some arguments end up using `RDTSC` in userspace, triggering a `SIGSEGV`.
 See `vdso(7)` for more information on how this works, and how glibc is
 involved. The solution is to wrap `gettimeofday()`, `clock_gettime()`
 (either entirely, or just some of its arguments), and `time()`, and force
 them to use their true syscall equivalents. If they go through their glibc
 functions, they'll use the vDSO mapping, and occur in userspace.

 This fix should be very simple, as long as Firefox does not manually use a
 TSC instruction in asm in its code by itself (in which case you'd have to
 patch around that). If it doesn't do that, then all you'd have to do is
 wrap a few functions like so:

 {{{
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <sys/time.h>
 #include <time.h>

 int gettimeofday(struct timeval *tv, struct timezone *tz)
 {
     return syscall(SYS_gettimeofday, tv, tz);
 }

 int clock_gettime(clockid_t clk_id, struct timespec *tp)
 {
     return syscall(SYS_clock_gettime, clk_id, tp);
 }

 time_t time(time_t *tloc)
 {
     return syscall(SYS_time, tloc);
 }
 }}}

 If Firefox tries to call any of these syscalls from glibc, hooking it
 using `LD_PRELOAD` or so with these functions should prevent it from
 deferring to userspace execution as a vDSO, and instead use a true
 syscall.

 On a slight tangent, given that this would disable so many of the vDSOs
 that exist, in the long-term it might be a good idea to look into a way to
 completely disable all access to the vDSO and VVAR, if it's possible to do
 that on a per-process basis (it also seems that modern x86_64 kernels
 cannot have it disabled globally by adding `vdso=0` to the kernel boot
 parameters either. Despite what the documentation says, the code says
 otherwise). vDSOs have been abused in combination with other exploit
 primitives for sandbox escapes and privesc. For example CVE-2016-5195
 could escape sandboxes by overwriting the vDSO and waiting for a process
 outside the sandbox to call it. Other vulnerabilities that lead to turning
 read-only pages writable would lead to that issue as well, even if mapping
 sensitive files like `/etc/passwd` or `/bin/su` isn't possible due to a
 strict sandbox. I'm not entirely sure if simply preventing vDSO and VVAR
 from being loaded is sufficient, but if so, then disabling it entirely
 would be an even better solution (and glibc will gracefully fall back to
 using native syscalls if it detects this). But in the meantime, hooking
 the glibc functions and using `syscall()` to call the native syscalls
 works fine for the purpose of safely disabling `RDTSC` and `RDTSCP`.

 Oh, and another note. vDSO calls bypass seccomp (and strace) by nature, so
 if you disable vDSO, you'll suddenly see a couple syscalls that previously
 didn't seem to exist, so unless you have whitelisted things like `time()`
 and `gettimeofday()`, you may see new violations that you didn't see
 before.

 As for anyone still using emulated, or god forbid, native vsyscalls who
 haven't moved onto vDSO, screw them. A sandbox won't do much to protect
 them anyway until they upgrade to a modern kernel.

 Information about vDSO:
 http://blog.tinola.com/?e=5
 https://www.linuxjournal.com/content/creating-vdso-colonels-other-chicken
 https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-3.html
 http://man7.org/linux/man-pages/man7/vdso.7.html
 http://lxr.free-electrons.com/source/arch/x86/entry/vdso/

 Information about side-channel attacks:
 https://www.tau.ac.il/~tromer/papers/cache-joc-20090619.pdf (EVICT+TIME
 and PRIME+PROBE)
 https://eprint.iacr.org/2013/448.pdf (FLUSH+RELOAD)
 https://gruss.cc/files/flushflush.pdf (FLUSH+FLUSH)

 Information about keystroke dynamics:
 https://www.cs.cmu.edu/~keystroke/KillourhyMaxion09.pdf
 https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3835878/
 https://people.eecs.berkeley.edu/~daw/papers/ssh-use01.pdf

 Information about the TSC and disabling it:
 https://en.wikipedia.org/wiki/Control_register#CR4
 http://x86.renejeschke.de/html/file_module_x86_id_278.html
 http://man7.org/linux/man-pages/man2/prctl.2.html

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/21010>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list