[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [tor-bugs] #21010 [Applications/Tor Browser Sandbox]: Disable RDTSC/RDTSCP to limit side-channel attacks
#21010: Disable RDTSC/RDTSCP to limit side-channel attacks
----------------------------------------------+-------------------------
Reporter: cypherpunks | Owner: yawning
Type: enhancement | Status: new
Priority: High | Milestone:
Component: Applications/Tor Browser Sandbox | Version:
Severity: Normal | Resolution:
Keywords: | Actual Points:
Parent ID: | Points:
Reviewer: | Sponsor:
----------------------------------------------+-------------------------
Comment (by cypherpunks):
I wrote a stub to test Firefox with TSC instructions disabled, but it
segfaulted (though it solves the issue for the majority of programs). I
disassembled all the libraries and searched for mentions of `RDTSC`, and
this is what I found:
{{{
$ cd /usr/local/lib64/tor-browser
$ lddtree -l firefox *.so | sort -u | while read -r so; do (echo -n "$so:
"; objdump -M intel -D "$so" | grep -c rdtsc) | sed '/: 0$/d'; done
/lib64/ld-linux-x86-64.so.2: 17
/lib64/libc.so.6: 2
/lib64/libpthread.so.0: 2
/lib64/libresolv.so.2: 1
./libfreebl3.so: 1
./libxul.so: 21
/usr/lib64/libfreetype.so.6: 1
/usr/lib64/libgdk-x11-2.0.so.0: 3
/usr/lib64/libgtk-x11-2.0.so.0: 2
/usr/lib64/libX11.so.6: 1
}}}
`libxul.so` has the most instances, in symbols related to JS objects.
Given how huge it is, I wouldn't be surprised if Firefox never actually
hits those code paths. We'll cross that bridge when we get to it.
The occurrence in `libresolve.so.2` is near the beginning of
`__res_nmkquery`. I don't think it'll be an issue, considering Tor Browser
doesn't do domain resolution directly but uses the SOCKS5/SOCKS4a protocol
and lets Tor take care of it. From `res_nmkquery(3)`:
{{{
The res_nmkquery() and res_mkquery() functions construct a query mes-
sage in buf of length buflen for the domain name dname. The query type
op is usually QUERY, but can be any of the types defined in
<arpa/nameser.h>. newrr is currently unused.
}}}
One occurrence in `libc.so.6` is in `tempnam`, and the other in `__fork`.
The instances in all the others not mentioned here are false positives
(e.g. from `.rodata` or in strings).
The pthread library however calls it twice. Once at the very beginning of
`start_thread`, and again at the very beginning of
`__pthread_clock_gettime`:
{{{
$ objdump -M intel -D /lib64/libpthread.so.0 | grep -B7 rdtsc
0000000000007480 <start_thread>:
7480: 53 push rbx
7481: 48 81 ec b0 10 00 00 sub rsp,0x10b0
7488: 48 83 0c 24 00 or QWORD PTR [rsp],0x0
748d: 48 81 c4 20 10 00 00 add rsp,0x1020
7494: 48 89 fb mov rbx,rdi
7497: 48 89 7c 24 08 mov QWORD PTR [rsp+0x8],rdi
749c: 0f 31 rdtsc
--
000000000000e950 <__pthread_clock_gettime>:
e950: 55 push rbp
e951: 53 push rbx
e952: 48 81 ec 38 10 00 00 sub rsp,0x1038
e959: 48 83 0c 24 00 or QWORD PTR [rsp],0x0
e95e: 48 81 c4 20 10 00 00 add rsp,0x1020
e965: 48 89 d3 mov rbx,rdx
e968: 0f 31 rdtsc
}}}
Reading through the glibc source, in `nptl/pthread_create.c`, it uses the
macro `HP_TIMING_NOW`, defined in `ntpl/perf.c` to use `RDTSC` to save the
time that the thread was started, if `HP_TIMING_AVAIL` is defined.
The second symbol is in `nptl/pthread_clock_gettime.c`, and is called
immediately after the function begins.
It seems this culprit is `__fork` from glibc, since making the stub fork
before returning to the real main function triggers a segfault. In the the
glibc source, in `sysdeps/nptl/fork.c`, `HP_TIMING_NOW` is used, also if
the macro `HP_TIMING_AVAIL` is defined. My guess is these are the
functions that'll need to be hooked in order to make this work with
threaded/forking programs like Firefox.
Relevant chunks (for glibc-2.22):
`ntpl/perf.c:705`
{{{
#ifdef i386
#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A"
(Var))
#elif defined __x86_64__
# define HP_TIMING_NOW(Var) \
({ unsigned int _hi, _lo; \
asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
(Var) = ((unsigned long long int) _hi << 32) | _lo; })
#elif defined __ia64__
#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mov %0=ar.itc" :
"=r" (Var) : : "memory")
#else
#error "HP_TIMING_NOW missing"
#endif
}}}
`sysdeps/nptl/fork.c:145`
{{{
#if HP_TIMING_AVAIL
/* The CPU clock of the thread and process have to be set to zero.
*/
hp_timing_t now;
HP_TIMING_NOW (now);
THREAD_SETMEM (self, cpuclock_offset, now);
GL(dl_cpuclock_offset) = now;
#endif
}}}
`nptl/pthread_create.c:258`
{{{
#if HP_TIMING_AVAIL
/* Remember the time when the thread was started. */
hp_timing_t now;
HP_TIMING_NOW (now);
THREAD_SETMEM (pd, cpuclock_offset, now);
#endif
}}}
`ntpl/pthread_clock_gettime.c:30`
{{{
hp_timing_t tsc;
/* Get the current counter. */
HP_TIMING_NOW (tsc);
}}}
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/21010#comment:4>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
_______________________________________________
tor-bugs mailing list
tor-bugs@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-bugs