Wednesday, January 3, 2018

Reading privileged memory with a side-channel

Posted by Jann Horn, Project Zero


We have discovered that CPU data cache timing can be abused to efficiently leak information out of mis-speculated execution, leading to (at worst) arbitrary virtual memory read vulnerabilities across local security boundaries in various contexts.

Variants of this issue are known to affect many modern processors, including certain processors by Intel, AMD and ARM. For a few Intel and AMD CPU models, we have exploits that work against real software. We reported this issue to Intel, AMD and ARM on 2017-06-01 [1].

So far, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are three known variants of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue:

  • Variant 1: bounds check bypass (CVE-2017-5753)
  • Variant 2: branch target injection (CVE-2017-5715)
  • Variant 3: rogue data cache load (CVE-2017-5754)

Before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issues described here were publicly disclosed, Daniel Gruss, Moritz Lipp, Yuval Yarom, Paul Kocher, Daniel Genkin, Michael Schwarz, Mike Hamburg, Stefan Mangard, Thomas Prescher and Werner Haas also reported cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir [writeups/blogposts/paper drafts] are at:


During cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 course of our research, we developed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following proofs of concept (PoCs):

  1. A PoC that demonstrates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 basic principles behind variant 1 in userspace on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tested Intel Haswell Xeon CPU, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMD FX CPU, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMD PRO CPU and an ARM Cortex A57 [2]. This PoC only tests for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to read data inside mis-speculated execution within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same process, without crossing any privilege boundaries.
  2. A PoC for variant 1 that, when running with normal user privileges under a modern Linux kernel with a distro-standard config, can perform arbitrary reads in a 4GiB range [3] in kernel virtual memory on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's BPF JIT is enabled (non-default configuration), it also works on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMD PRO CPU. On cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU, kernel virtual memory can be read at a rate of around 2000 bytes per second after around 4 seconds of startup time. [4]
  3. A PoC for variant 2 that, when running with root privileges inside a KVM guest created using virt-manager on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU, with a specific (now outdated) version of Debian's distro kernel [5] running on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, can read host kernel memory at a rate of around 1500 bytes/second, with room for optimization. Before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack can be performed, some initialization has to be performed that takes roughly between 10 and 30 minutes for a machine with 64GiB of RAM; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 needed time should scale roughly linearly with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 amount of host RAM. (If 2MB hugepages are available to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 guest, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initialization should be much faster, but that hasn't been tested.)
  4. A PoC for variant 3 that, when running with normal user privileges, can read kernel memory on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU under some precondition. We believe that this precondition is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 targeted kernel memory is present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L1D cache.

For interesting resources around this topic, look down into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 "Literature" section.

A warning regarding explanations about processor internals in this blogpost: This blogpost contains a lot of speculation about hardware internals based on observed behavior, which might not necessarily correspond to what processors are actually doing.

We have some ideas on possible mitigations and provided some of those ideas to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor vendors; however, we believe that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor vendors are in a much better position than we are to design and evaluate mitigations, and we expect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source of authoritative guidance.

The PoC code and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 writeups that we sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU vendors are available here: https://bugs.chromium.org/p/project-zero/issues/detail?id=1272.

Tested Processors

  • Intel(R) Xeon(R) CPU E5-1650 v3 @ 3.50GHz (called "Intel Haswell Xeon CPU" in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of this document)
  • AMD FX(tm)-8320 Eight-Core Processor (called "AMD FX CPU" in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of this document)
  • AMD PRO A8-9600 R7, 10 COMPUTE CORES 4C+6G (called "AMD PRO CPU" in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of this document)
  • An ARM Cortex A57 core of a Google Nexus 5x phone [6] (called "ARM Cortex A57" in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of this document)

Glossary

retire: An instruction retires when its results, e.g. register writes and memory writes, are committed and made visible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system. Instructions can be executed out of order, but must always retire in order.

logical processor core: A logical processor core is what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 operating system sees as a processor core. With hyperthreading enabled, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of logical cores is a multiple of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of physical cores.

cached/uncached data: In this blogpost, "uncached" data is data that is only present in main memory, not in any of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache levels of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU. Loading uncached data will typically take over 100 cycles of CPU time.

speculative execution: A processor can execute past a branch without knowing whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it will be taken or where its target is, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore executing instructions before it is known whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y should be executed. If this speculation turns out to have been incorrect, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU can discard cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting state without architectural effects and continue execution on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct execution path. Instructions do not retire before it is known that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct execution path.

mis-speculation window: The time window during which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU speculatively executes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wrong code and has not yet detected that mis-speculation has occurred.

Variant 1: Bounds check bypass

This section explains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 common cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory behind all three variants and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory behind our PoC for variant 1 that, when running in userspace under a Debian distro kernel, can perform arbitrary reads in a 4GiB region of kernel memory in at least cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following configurations:

  • Intel Haswell Xeon CPU, eBPF JIT is off (default state)
  • Intel Haswell Xeon CPU, eBPF JIT is on (non-default state)
  • AMD PRO CPU, eBPF JIT is on (non-default state)

The state of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF JIT can be toggled using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 net.core.bpf_jit_enable sysctl.

Theoretical explanation

The Intel Optimization Reference Manual says cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following regarding Sandy Bridge (and later microarchitectural revisions) in section 2.3.2.3 ("Branch Prediction"):

Branch prediction predicts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch target and enables cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365
processor to begin executing instructions long before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch
true execution path is known.

In section 2.3.5.2 ("L1 DCache"):

Loads can:
[...]
  • Be carried out speculatively, before preceding branches are resolved.
  • Take cache misses out of order and in an overlapped manner.

Intel's Software Developer's Manual [7] states in Volume 3A, section 11.7 ("Implicit Caching (Pentium 4, Intel Xeon, and P6 family processors"):

Implicit caching occurs when a memory element is made potentially cacheable, although cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 element may never have been accessed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 normal von Neumann sequence. Implicit caching occurs on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 P6 and more recent processor families due to aggressive prefetching, branch prediction, and TLB miss handling. Implicit caching is an extension of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behavior of existing Intel386, Intel486, and Pentium processor systems, since software running on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se processor families also has not been able to deterministically predict cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behavior of instruction prefetch.
Consider cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code sample below. If arr1->length is uncached, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor can speculatively load data from arr1->data[untrusted_offset_from_caller]. This is an out-of-bounds read. That should not matter because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor will effectively roll back cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 execution state when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch has executed; none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 speculatively executed instructions will retire (e.g. cause registers etc. to be affected).

struct array {
 unsigned long length;
 unsigned char data[];
};
struct array *arr1 = ...;
unsigned long untrusted_offset_from_caller = ...;
if (untrusted_offset_from_caller < arr1->length) {
 unsigned char value = arr1->data[untrusted_offset_from_caller];
 ...
}
However, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following code sample, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re's an issue. If arr1->length, arr2->data[0x200] and arr2->data[0x300] are not cached, but all ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r accessed data is, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch conditions are predicted as true, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor can do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following speculatively before arr1->length has been loaded and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 execution is re-steered:

  • load value = arr1->data[untrusted_offset_from_caller]
  • start a load from a data-dependent offset in arr2->data, loading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding cache line into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L1 cache

struct array {
 unsigned long length;
 unsigned char data[];
};
struct array *arr1 = ...; /* small array */
struct array *arr2 = ...; /* array of size 0x400 */
/* >0x400 (OUT OF BOUNDS!) */
unsigned long untrusted_offset_from_caller = ...;
if (untrusted_offset_from_caller < arr1->length) {
 unsigned char value = arr1->data[untrusted_offset_from_caller];
 unsigned long index2 = ((value&1)*0x100)+0x200;
 if (index2 < arr2->length) {
   unsigned char value2 = arr2->data[index2];
 }
}

After cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 execution has been returned to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 non-speculative path because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor has noticed that untrusted_offset_from_caller is bigger than arr1->length, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line containing arr2->data[index2] stays in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L1 cache. By measuring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time required to load arr2->data[0x200] and arr2->data[0x300], an attacker can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of index2 during speculative execution was 0x200 or 0x300 - which discloses whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r arr1->data[untrusted_offset_from_caller]&1 is 0 or 1.

To be able to actually use this behavior for an attack, an attacker needs to be able to cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 execution of such a vulnerable code pattern in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 targeted context with an out-of-bounds index. For this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerable code pattern must eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r be present in existing code, or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re must be an interpreter or JIT engine that can be used to generate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerable code pattern. So far, we have not actually identified any existing, exploitable instances of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerable code pattern; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC for leaking kernel memory using variant 1 uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF interpreter or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF JIT engine, which are built into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel and accessible to normal users.

A minor variant of this could be to instead use an out-of-bounds read to a function pointer to gain control of execution in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mis-speculated path. We did not investigate this variant furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.

Attacking cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel

This section describes in more detail how variant 1 can be used to leak Linux kernel memory using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF bytecode interpreter and JIT engine. While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are many interesting potential targets for variant 1 attacks, we chose to attack cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux in-kernel eBPF JIT/interpreter because it provides more control to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker than most ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r JITs.

The Linux kernel supports eBPF since version 3.18. Unprivileged userspace code can supply bytecode to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel that is verified by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n:

  • eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r interpreted by an in-kernel bytecode interpreter
  • or translated to native machine code that also runs in kernel context using a JIT engine (which translates individual bytecode instructions without performing any furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r optimizations)

Execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bytecode can be triggered by attaching cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF bytecode to a socket as a filter and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n sending data through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r end of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 socket.

Whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JIT engine is enabled depends on a run-time configuration setting - but at least on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tested Intel processor, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack works independent of that setting.

Unlike classic BPF, eBPF has data types like data arrays and function pointer arrays into which eBPF bytecode can index. Therefore, it is possible to create cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code pattern described above in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel using eBPF bytecode.

eBPF's data arrays are less efficient than its function pointer arrays, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack will use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latter where possible.

Both machines on which this was tested have no SMAP, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC relies on that (but it shouldn't be a precondition in principle).

Additionally, at least on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel machine on which this was tested, bouncing modified cache lines between cores is slow, apparently because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MESI protocol is used for cache coherence [8]. Changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference counter of an eBPF array on one physical CPU core causes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference counter to be bounced over to that CPU core, making reads of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference counter on all ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r CPU cores slow until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 changed reference counter has been written back to memory. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference counter of an eBPF array are stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same cache line, this also means that changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference counter on one physical CPU core causes reads of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF array's length to be slow on ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r physical CPU cores (intentional false sharing).

The attack uses two eBPF programs. The first one tail-calls through a page-aligned eBPF function pointer array prog_map at a configurable index. In simplified terms, this program is used to determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of prog_map by guessing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset from prog_map to a userspace address and tail-calling through prog_map at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 guessed offsets. To cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction to predict that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset is below cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of prog_map, tail calls to an in-bounds index are performed in between. To increase cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mis-speculation window, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of prog_map is bounced to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r core. To test whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r an offset guess was successful, it can be tested whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 userspace address has been loaded into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache.

Because such straightforward brute-force guessing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address would be slow, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following optimization is used: 215 adjacent userspace memory mappings [9], each consisting of 24 pages, are created at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 userspace address user_mapping_area, covering a total area of 231 bytes. Each mapping maps cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same physical pages, and all mappings are present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pagetables.



This permits cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack to be carried out in steps of 231 bytes. For each step, after causing an out-of-bounds access through prog_map, only one cache line each from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first 24 pages of user_mapping_area have to be tested for cached memory. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L3 cache is physically indexed, any access to a virtual address mapping a physical page will cause all ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r virtual addresses mapping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same physical page to become cached as well.

When this attack finds a hit—a cached memory location—cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 upper 33 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel address are known (because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can be derived from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address guess at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hit occurred), and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low 16 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address are also known (from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset inside user_mapping_area at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hit was found). The remaining part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of user_mapping_area is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 middle.



The remaining bits in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 middle can be determined by bisecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining address space: Map two physical pages to adjacent ranges of virtual addresses, each virtual address range cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining search space, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining address bit-wise.

At this point, a second eBPF program can be used to actually leak data. In pseudocode, this program looks as follows:

uint64_t bitmask = ;
uint64_t bitshift_selector = ;
uint64_t prog_array_base_offset = ;
uint64_t secret_data_offset = ;
// index will be bounds-checked by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 runtime,
// but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bounds check will be bypassed speculatively
uint64_t secret_data = bpf_map_read(array=victim_array, index=secret_data_offset);
// select a single bit, move it to a specific position, and add cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base offset
uint64_t progmap_index = (((secret_data & bitmask) >> bitshift_selector) << 7) + prog_array_base_offset;
bpf_tail_call(prog_map, progmap_index);

This program reads 8-byte-aligned 64-bit values from an eBPF data array "victim_map" at a runtime-configurable offset and bitmasks and bit-shifts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value so that one bit is mapped to one of two values that are 27 bytes apart (sufficient to not land in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same or adjacent cache lines when used as an array index). Finally it adds a 64-bit offset, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting value as an offset into prog_map for a tail call.

This program can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be used to leak memory by repeatedly calling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF program with an out-of-bounds offset into victim_map that specifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data to leak and an out-of-bounds offset into prog_map that causes prog_map + offset to point to a userspace memory area. Misleading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction and bouncing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache lines works cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same way as for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first eBPF program, except that now, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line holding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 length of victim_map must also be bounced to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r core.

Variant 2: Branch target injection

This section describes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory behind our PoC for variant 2 that, when running with root privileges inside a KVM guest created using virt-manager on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU, with a specific version of Debian's distro kernel running on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, can read host kernel memory at a rate of around 1500 bytes/second.

Basics

Prior research (see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Literature section at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end) has shown that it is possible for code in separate security contexts to influence each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r's branch prediction. So far, this has only been used to infer information about where code is located (in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, to create interference from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker); however, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 basic hypocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365sis of this attack variant is that it can also be used to redirect execution of code in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim context (in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, to create interference from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 victim; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r way around).



The basic idea for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack is to target victim code that contains an indirect branch whose target address is loaded from memory and flush cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line containing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target address out to main memory. Then, when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU reaches cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect branch, it won't know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 true destination of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 jump, and it won't be able to calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 true destination until it has finished loading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache line back into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU, which takes a few hundred cycles. Therefore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a time window of typically over 100 cycles in which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU will speculatively execute instructions based on branch prediction.

Haswell branch prediction internals

Some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 internals of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction implemented by Intel's processors have already been published; however, getting this attack to work properly required significant furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r experimentation to determine additional details.

This section focuses on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction internals that were experimentally derived from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Intel Haswell Xeon CPU.

Haswell seems to have multiple branch prediction mechanisms that work very differently:

  • A generic branch predictor that can only store one target per source address; used for all kinds of jumps, like absolute jumps, relative jumps and so on.
  • A specialized indirect call predictor that can store multiple targets per source address; used for indirect calls.
  • (There is also a specialized return predictor, according to Intel's optimization manual, but we haven't analyzed that in detail yet. If this predictor could be used to reliably dump out some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call stack through which a VM was entered, that would be very interesting.)

Generic predictor

The generic branch predictor, as documented in prior research, only uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower 31 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last byte of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source instruction for its prediction. If, for example, a branch target buffer (BTB) entry exists for a jump from 0x4141.0004.1000 to 0x4141.0004.5123, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic predictor will also use it to predict a jump from 0x4242.0004.1000. When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 higher bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address differ like this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 higher bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 predicted destination change togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r with it—in this case, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 predicted destination address will be 0x4242.0004.5123—so apparently this predictor doesn't store cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 full, absolute destination address.

Before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower 31 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address are used to look up a BTB entry, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are folded togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r using XOR. Specifically, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following bits are folded togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r:

bit A
bit B
0x40.0000
0x2000
0x80.0000
0x4000
0x100.0000
0x8000
0x200.0000
0x1.0000
0x400.0000
0x2.0000
0x800.0000
0x4.0000
0x2000.0000
0x10.0000
0x4000.0000
0x20.0000

In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, if a source address is XORed with both numbers in a row of this table, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predictor will not be able to distinguish cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting address from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original source address when performing a lookup. For example, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predictor is able to distinguish source addresses 0x100.0000 and 0x180.0000, and it can also distinguish source addresses 0x100.0000 and 0x180.8000, but it can't distinguish source addresses 0x100.0000 and 0x140.2000 or source addresses 0x100.0000 and 0x180.4000. In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following, this will be referred to as aliased source addresses.

When an aliased source address is used, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predictor will still predict cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same target as for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unaliased source address. This indicates that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predictor stores a truncated absolute destination address, but that hasn't been verified.

Based on observed maximum forward and backward jump distances for different source addresses, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low 32-bit half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target address could be stored as an absolute 32-bit value with an additional bit that specifies whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 jump from source to target crosses a 232 boundary; if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 jump crosses such a boundary, bit 31 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address determines whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 high half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction pointer should increment or decrement.

Indirect call predictor

The inputs of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BTB lookup for this mechanism seem to be:

  • The low 12 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source instruction (we are not sure whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it's cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last byte) or a subset of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.
  • The branch history buffer state.

If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call predictor can't resolve a branch, it is resolved by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic predictor instead. Intel's optimization manual hints at this behavior: "Indirect Calls and Jumps. These may eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r be predicted as having a monotonic target or as having targets that vary in accordance with recent program behavior."

The branch history buffer (BHB) stores information about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last 29 taken branches - basically a fingerprint of recent control flow - and is used to allow better prediction of indirect calls that can have multiple targets.

The update function of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BHB works as follows (in pseudocode; src is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last byte of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source instruction, dst is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination address):

void bhb_update(uint58_t *bhb_state, unsigned long src, unsigned long dst) {
 *bhb_state <<= 2;
 *bhb_state ^= (dst & 0x3f);
 *bhb_state ^= (src & 0xc0) >> 6;
 *bhb_state ^= (src & 0xc00) >> (10 - 2);
 *bhb_state ^= (src & 0xc000) >> (14 - 4);
 *bhb_state ^= (src & 0x30) << (6 - 4);
 *bhb_state ^= (src & 0x300) << (8 - 8);
 *bhb_state ^= (src & 0x3000) >> (12 - 10);
 *bhb_state ^= (src & 0x30000) >> (16 - 12);
 *bhb_state ^= (src & 0xc0000) >> (18 - 14);
}

Some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BHB state seem to be folded togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r using XOR when used for a BTB access, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 precise folding function hasn't been understood yet.

The BHB is interesting for two reasons. First, knowledge about its approximate behavior is required in order to be able to accurately cause collisions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call predictor. But it also permits dumping out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BHB state at any repeatable program state at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker can execute code - for example, when attacking a hypervisor, directly after a hypercall. The dumped BHB state can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n be used to fingerprint cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hypervisor or, if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker has access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hypervisor binary, to determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low 20 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hypervisor load address (in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case of KVM: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low 20 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address of kvm-intel.ko).

Reverse-Engineering Branch Predictor Internals

This subsection describes how we reverse-engineered cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 internals of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Haswell branch predictor. Some of this is written down from memory, since we didn't keep a detailed record of what we were doing.

We initially attempted to perform BTB injections into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic predictor, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 knowledge from prior research that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic predictor only looks at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address and that only a partial target address is stored. This kind of worked - however, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 injection success rate was very low, below 1%. (This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method we used in our preliminary PoCs for method 2 against modified hypervisors running on Haswell.)

We decided to write a userspace test case to be able to more easily test branch predictor behavior in different situations.

Based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 assumption that branch predictor state is shared between hyperthreads [10], we wrote a program of which two instances are each pinned to one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two logical processors running on a specific physical core, where one instance attempts to perform branch injections while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r measures how often branch injections are successful. Both instances were executed with ASLR disabled and had cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same code at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same addresses. The injecting process performed indirect calls to a function that accesses a (per-process) test variable; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 measuring process performed indirect calls to a function that tests, based on timing, whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-process test variable is cached, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n evicts it using CLFLUSH. Both indirect calls were performed through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same callsite. Before each indirect call, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function pointer stored in memory was flushed out to main memory using CLFLUSH to widen cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 speculation time window. Additionally, because of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reference to "recent program behavior" in Intel's optimization manual, a bunch of conditional branches that are always taken were inserted in front of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call.

In this test, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 injection success rate was above 99%, giving us a base setup for future experiments.



We cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n tried to figure out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 details of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 prediction scheme. We assumed that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 prediction scheme uses a global branch history buffer of some kind.

To determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 duration for which branch information stays in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer, a conditional branch that is only taken in one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two program instances was inserted in front of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 series of always-taken conditional jumps, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of always-taken conditional jumps (N) was varied. The result was that for N=25, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor was able to distinguish cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branches (misprediction rate under 1%), but for N=26, it failed to do so (misprediction rate over 99%).
Therefore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer had to be able to store information about at least cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last 26 branches.

The code in one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two program instances was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n moved around in memory. This revealed that only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower 20 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source and target addresses have an influence on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer.

Testing with different types of branches in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two program instances revealed that static jumps, taken conditional jumps, calls and returns influence cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same way; non-taken conditional jumps don't influence it; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last byte of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source instruction is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one that counts; IRETQ doesn't influence cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer state (which is useful for testing because it permits creating program flow that is invisible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer).

Moving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last conditional branch before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call around in memory multiple times revealed that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer contents can be used to distinguish many different locations of that last conditional branch instruction. This suggests that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer doesn't store a list of small history values; instead, it seems to be a larger buffer in which history data is mixed togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.

However, a history buffer needs to "forget" about past branches after a certain number of new branches have been taken in order to be useful for branch prediction. Therefore, when new data is mixed into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer, this can not cause information in bits that are already present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer to propagate downwards - and given that, upwards combination of information probably wouldn't be very useful eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. Given that branch prediction also must be very fast, we concluded that it is likely that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 update function of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer left-shifts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 old history buffer, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n XORs in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new state (see diagram).



If this assumption is correct, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer contains a lot of information about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most recent branches, but only contains as many bits of information as are shifted per history buffer update about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last branch about which it contains any data. Therefore, we tested whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r flipping different bits in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source and target addresses of a jump followed by 32 always-taken jumps with static source and target allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction to disambiguate an indirect call. [11]

With 32 static jumps in between, no bit flips seemed to have an influence, so we decreased cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of static jumps until a difference was observable. The result with 28 always-taken jumps in between was that bits 0x1 and 0x2 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target and bits 0x40 and 0x80 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source had such an influence; but flipping both 0x1 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target and 0x40 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source or 0x2 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target and 0x80 in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source did not permit disambiguation. This shows that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 per-insertion shift of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer is 2 bits and shows which data is stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 least significant bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer. We cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n repeated this with decreased amounts of fixed jumps after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bit-flipped jump to determine which information is stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining bits.

Reading host memory from a KVM guest

Locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel

Our PoC locates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel in several steps. The information that is determined and necessary for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next steps of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack consists of:

  • lower 20 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of kvm-intel.ko
  • full address of kvm.ko
  • full address of vmlinux

Looking back, this is unnecessarily complicated, but it nicely demonstrates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 various techniques an attacker can use. A simpler way would be to first determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of vmlinux, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n bisect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 addresses of kvm.ko and kvm-intel.ko.

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first step, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of kvm-intel.ko is leaked. For this purpose, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer state after guest entry is dumped out. Then, for every possible value of bits 12..19 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address of kvm-intel.ko, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 expected lowest 16 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer are computed based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address guess and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 known offsets of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last 8 branches before guest entry, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results are compared against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lowest 16 bits of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 leaked history buffer state.

The branch history buffer state is leaked in steps of 2 bits by measuring misprediction rates of an indirect call with two targets. One way cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call is reached is from a vmcall instruction followed by a series of N branches whose relevant source and target address bits are all zeroes. The second way cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call is reached is from a series of controlled branches in userspace that can be used to write arbitrary values into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer.
Misprediction rates are measured as in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 section "Reverse-Engineering Branch Predictor Internals", using one call target that loads a cache line and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r one that checks whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same cache line has been loaded.



With N=29, mispredictions will occur at a high rate if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 controlled branch history buffer value is zero because all history buffer state from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hypercall has been erased. With N=28, mispredictions will occur if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 controlled branch history buffer value is one of 0<<(28*2), 1<<(28*2), 2<<(28*2), 3<<(28*2) - by testing all four possibilities, it can be detected which one is right. Then, for decreasing values of N, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 four possibilities are {0|1|2|3}<<(28*2) | (history_buffer_for(N+1) >> 2). By repeating this for decreasing values for N, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch history buffer value for N=0 can be determined.

At this point, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 low 20 bits of kvm-intel.ko are known; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next step is to roughly locate kvm.ko.
For this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic branch predictor is used, using data inserted into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BTB by an indirect call from kvm.ko to kvm-intel.ko that happens on every hypercall; this means that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call has to be leaked out of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 BTB.

kvm.ko will probably be located somewhere in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range from 0xffffffffc0000000 to 0xffffffffc4000000, with page alignment (0x1000). This means that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first four entries in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 table in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 section "Generic Predictor" apply; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re will be 24-1=15 aliasing addresses for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct one. But that is also an advantage: It cuts down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 search space from 0x4000 to 0x4000/24=1024.

To find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right address for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source or one of its aliasing addresses, code that loads data through a specific register is placed at all possible call targets (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 leaked low 20 bits of kvm-intel.ko plus cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 in-module offset of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call target plus a multiple of 220) and indirect calls are placed at all possible call sources. Then, alternatingly, hypercalls are performed and indirect calls are performed through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 different possible non-aliasing call sources, with randomized history buffer state that prevents cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specialized prediction from working. After this step, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are 216 remaining possibilities for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address of kvm.ko.

Next, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address of vmlinux can be determined in a similar way, using an indirect call from vmlinux to kvm.ko. Luckily, none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bits which are randomized in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 load address of vmlinux  are folded togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, so unlike when locating kvm.ko, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result will directly be unique. vmlinux has an alignment of 2MiB and a randomization range of 1GiB, so cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are still only 512 possible addresses.
Because (as far as we know) a simple hypercall won't actually cause indirect calls from vmlinux to kvm.ko, we instead use port I/O from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 status register of an emulated serial port, which is present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 default configuration of a virtual machine created with virt-manager.

The only remaining piece of information is which one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 16 aliasing load addresses of kvm.ko is actually correct. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source address of an indirect call to kvm.ko is known, this can be solved using bisection: Place code at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 various possible targets that, depending on which instance of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code is speculatively executed, loads one of two cache lines, and measure which one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache lines gets loaded.

Identifying cache sets

The PoC assumes that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 VM does not have access to hugepages.To discover eviction sets for all L3 cache sets with a specific alignment relative to a 4KiB page boundary, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC first allocates 25600 pages of memory. Then, in a loop, it selects random subsets of all remaining unsorted pages such that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 expected number of sets for which an eviction set is contained in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 subset is 1, reduces each subset down to an eviction set by repeatedly accessing its cache lines and testing whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache lines are always cached (in which case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y're probably not part of an eviction set) and attempts to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new eviction set to evict all remaining unsorted cache lines to determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same cache set [12].

Locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host-virtual address of a guest page

Because this attack uses a FLUSH+RELOAD approach for leaking data, it needs to know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host-kernel-virtual address of one guest page. Alternative approaches such as PRIME+PROBE should work without that requirement.

The basic idea for this step of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack is to use a branch target injection attack against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hypervisor to load an attacker-controlled address and test whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r that caused cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 guest-owned page to be loaded. For this, a gadget that simply loads from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory location specified by R8 can be used - R8-R11 still contain guest-controlled values when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first indirect call after a guest exit is reached on this kernel build.

We expected that an attacker would need to eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r know which eviction set has to be used at this point or brute-force it simultaneously; however, experimentally, using random eviction sets works, too. Our cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 observed behavior is actually cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of L1D and L2 evictions, which might be sufficient to permit a few instructions worth of speculative execution.

The host kernel maps (nearly?) all physical memory in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap area, including memory assigned to KVM guests. However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap is randomized (with a 1GiB alignment), in an area of size 128PiB. Therefore, directly bruteforcing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host-virtual address of a guest page would take a long time. It is not necessarily impossible; as a ballpark estimate, it should be possible within a day or so, maybe less, assuming 12000 successful injections per second and 30 guest pages that are tested in parallel; but not as impressive as doing it in a few minutes.

To optimize this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 problem can be split up: First, brute-force cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address using a gadget that can load from physical addresses, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n brute-force cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap region. Because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address can usually be assumed to be far below 128PiB, it can be brute-forced more efficiently, and brute-forcing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap region afterwards is also easier because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n address guesses with 1GiB alignment can be used.

To brute-force cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following gadget can be used:

ffffffff810a9def:       4c 89 c0                mov    rax,r8
ffffffff810a9df2:       4d 63 f9                movsxd r15,r9d
ffffffff810a9df5:       4e 8b 04 fd c0 b3 a6    mov    r8,QWORD PTR [r15*8-0x7e594c40]
ffffffff810a9dfc:       81
ffffffff810a9dfd:       4a 8d 3c 00             lea    rdi,[rax+r8*1]
ffffffff810a9e01:       4d 8b a4 00 f8 00 00    mov    r12,QWORD PTR [r8+rax*1+0xf8]
ffffffff810a9e08:       00

This gadget permits loading an 8-byte-aligned value from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 area around cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel text section by setting R9 appropriately, which in particular permits loading page_offset_base, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 start address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap. Then, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value that was originally in R8 - cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address guess minus 0xf8 - is added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous load, 0xfa is added to it, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result is dereferenced.

Cache set selection

To select cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct L3 eviction set, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following section is essentially executed with different eviction sets until it works.

Leaking data

At this point, it would normally be necessary to locate gadgets in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel code that can be used to actually leak data by reading from an attacker-controlled location, shifting and masking cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result appropriately and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of that as offset to an attacker-controlled address for a load. But piecing gadgets togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r and figuring out which ones work in a speculation context seems annoying. So instead, we decided to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eBPF interpreter, which is built into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel - while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is no legitimate way to invoke it from inside a VM, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel's text section is sufficient to make it usable for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack, just like with ordinary ROP gadgets.

The eBPF interpreter entry point has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following function signature:

static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn)

The second parameter is a pointer to an array of statically pre-verified eBPF instructions to be executed - which means that __bpf_prog_run() will not perform any type checks or bounds checks. The first parameter is simply stored as part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initial emulated register state, so its value doesn't matter.

The eBPF interpreter provides, among ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r things:

  • multiple emulated 64-bit registers
  • 64-bit immediate writes to emulated registers
  • memory reads from addresses stored in emulated registers
  • bitwise operations (including bit shifts) and arithmetic operations

To call cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interpreter entry point, a gadget that gives RSI and RIP control given R8-R11 control and controlled data at a known memory location is necessary. The following gadget provides this functionality:

ffffffff81514edd:       4c 89 ce                mov    rsi,r9
ffffffff81514ee0:       41 ff 90 b0 00 00 00    call   QWORD PTR [r8+0xb0]

Now, by pointing R8 and R9 at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping of a guest-owned page in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap, it is possible to speculatively execute arbitrary unvalidated eBPF bytecode in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel. Then, relatively straightforward bytecode can be used to leak data into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache.

Variant 3: Rogue data cache load


In summary, an attack using this variant of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue attempts to read kernel memory from userspace without misdirecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 control flow of kernel code. This works by using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code pattern that was used for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous variants, but in userspace. The underlying idea is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permission check for accessing an address might not be on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 critical path for reading data from memory to a register, where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permission check could have significant performance impact. Instead, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory read could make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read available to following instructions immediately and only perform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permission check asynchronously, setting a flag in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reorder buffer that causes an exception to be raised if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permission check fails.

We do have a few additions to make to Anders Fogh's blogpost:

"Imagine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following instruction executed in usermode
mov rax,[somekernelmodeaddress]
It will cause an interrupt when retired, [...]"

It is also possible to already execute that instruction behind a high-latency mispredicted branch to avoid taking a page fault. This might also widen cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 speculation window by increasing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 delay between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read from a kernel address and delivery of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 associated exception.

"First, I call a syscall that touches this memory. Second, I use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 prefetcht0 instruction to improve my odds of having cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address loaded in L1."

When we used prefetch instructions after doing a syscall, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack stopped working for us, and we have no clue why. Perhaps cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU somehow stores whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r access was denied on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last access and prevents cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack from working if that is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case?

"Fortunately I did not get a slow read suggesting that Intel null’s cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 result when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 access is not allowed."

That (read from kernel address returns all-zeroes) seems to happen for memory that is not sufficiently cached but for which pagetable entries are present, at least after repeated read attempts. For unmapped memory, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel address read does not return a result at all.

Ideas for furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r research

We believe that our research provides many remaining research topics that we have not yet investigated, and we encourage ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r public researchers to look into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se.
This section contains an even higher amount of speculation than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of this blogpost - it contains untested ideas that might well be useless.

Leaking without data cache timing

It would be interesting to explore whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are microarchitectural attacks ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than measuring data cache timing that can be used for exfiltrating data out of speculative execution.

Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r microarchitectures

Our research was relatively Haswell-centric so far. It would be interesting to see details e.g. on how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction of ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r modern processors works and how well it can be attacked.

Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r JIT engines

We developed a successful variant 1 attack against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JIT engine built into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Linux kernel. It would be interesting to see whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r attacks against more advanced JIT engines with less control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system are also practical - in particular, JavaScript engines.

More efficient scanning for host-virtual addresses and cache sets

In variant 2, while scanning for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host-virtual address of a guest-owned page, it might make sense to attempt to determine its L3 cache set first. This could be done by performing L3 evictions using an eviction pattern through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physmap, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n testing whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 eviction affected cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 guest-owned page.

The same might work for cache sets - use an L1D+L2 eviction set to evict cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function pointer in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel context, use a gadget in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel to evict an L3 set using physical addresses, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n use that to identify which cache sets guest lines belong to until a guest-owned eviction set has been constructed.

Dumping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 complete BTB state

Given that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generic BTB seems to only be able to distinguish 231-8 or fewer source addresses, it seems feasible to dump out cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 complete BTB state generated by e.g. a hypercall in a timeframe around cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 order of a few hours. (Scan for jump sources, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n for every discovered jump source, bisect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 jump target.) This could potentially be used to identify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 locations of functions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel is custom-built.

The source address aliasing would reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 usefulness somewhat, but because target addresses don't suffer from that, it might be possible to correlate (source,target) pairs from machines with different KASLR offsets and reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of candidate addresses based on KASLR being additive while aliasing is bitwise.

This could cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n potentially allow an attacker to make guesses about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel version or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 compiler used to build it based on jump offsets or distances between functions.

Variant 2: Leaking with more efficient gadgets

If sufficiently efficient gadgets are used for variant 2, it might not be necessary to evict host kernel function pointers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L3 cache at all; it might be sufficient to only evict cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m from L1D and L2.

Various speedups

In particular cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 variant 2 PoC is still a bit slow. This is probably partly because:

  • It only leaks one bit at a time; leaking more bits at a time should be doable.
  • It heavily uses IRETQ for hiding control flow from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor.

It would be interesting to see what data leak rate can be achieved using variant 2.

Leaking or injection through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return predictor

If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return predictor also doesn't lose its state on a privilege level change, it might be useful for eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel from inside a VM (in which case bisection could be used to very quickly discover cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 full address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host kernel) or injecting return targets (in particular if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return address is stored in a cache line that can be flushed out by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker and isn't reloaded before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return instruction).

However, we have not performed any experiments with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 return predictor that yielded conclusive results so far.

Leaking data out of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call predictor

We have attempted to leak target information out of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indirect call predictor, but haven't been able to make it work.

Vendor statements

The following statement were provided to us regarding this issue from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vendors to whom Project Zero disclosed this vulnerability:

Intel

Intel is committed to improving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 overall security of computer systems. The methods described here rely on common properties of modern microprocessors. Thus, susceptibility to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se methods is not limited to Intel processors, nor does it mean that a processor is working outside its intended functional specification. Intel is working closely with our ecosystem partners, as well as with ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r silicon vendors whose processors are affected, to design and distribute both software and hardware mitigations for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se methods.

For more information and links to useful resources, visit:

https://security-center.intel.com/advisory.aspx?intelid=INTEL-SA-00088&languageid=en-fr
http://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf

AMD

AMD provided cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following link: http://www.amd.com/en/corporate/speculative-execution

ARM

Arm recognises that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 speculation functionality of many modern high-performance processors, despite working as intended, can be used in conjunction with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 timing of cache operations to leak some information as described in this blog. Correspondingly, Arm has developed software mitigations that we recommend be deployed.

Specific details regarding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 affected processors and mitigations can be found at this website: https://developer.arm.com/support/security-update

Arm has included a detailed technical whitepaper as well as links to information from some of Arm’s architecture partners regarding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir specific implementations and mitigations.

Literature

Note that some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se documents - in particular Intel's documentation - change over time, so quotes from and references to it may not reflect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest version of Intel's documentation.

  • https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf: Intel's optimization manual has many interesting pieces of optimization advice that hint at relevant microarchitectural behavior; for example:
    • "Placing data immediately following an indirect branch can cause a performance problem. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data consists of all zeros, it looks like a long stream of ADDs to memory destinations and this can cause resource conflicts and slow down branch recovery. Also, data immediately following indirect branches may appear as branches to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predication [sic] hardware, which can branch off to execute ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r data pages. This can lead to subsequent self-modifying code problems."
    • "Loads can:[...]Be carried out speculatively, before preceding branches are resolved."
    • "Software should avoid writing to a code page in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same 1-KByte subpage that is being executed or fetching code in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same 2-KByte subpage of that is being written. In addition, sharing a page containing directly or speculatively executed code with anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r processor as a data page can trigger an SMC condition that causes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire pipeline of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 machine and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trace cache to be cleared. This is due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 self-modifying code condition."
    • "if mapped as WB or WT, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a potential for speculative processor reads to bring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 caches"
    • "Failure to map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 region as WC may allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 line to be speculatively read into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processor caches (via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wrong path of a mispredicted branch)."
  • https://software.intel.com/en-us/articles/intel-sdm: Intel's Software Developer Manuals
  • http://www.agner.org/optimize/microarchitecture.pdf: Agner Fog's documentation of reverse-engineered processor behavior and relevant cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory was very helpful for this research.
  • http://www.cs.binghamton.edu/~dima/micro16.pdf and https://github.com/felixwilhelm/mario_baslr: Prior research by Dmitry Evtyushkin, Dmitry Ponomarev and Nael Abu-Ghazaleh on abusing branch target buffer behavior to leak addresses that we used as a starting point for analyzing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch prediction of Haswell processors. Felix Wilhelm's research based on this provided cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 basic idea behind variant 2.
  • https://arxiv.org/pdf/1507.06955.pdf: The rowhammer.js research by Daniel Gruss, Clémentine Maurice and Stefan Mangard contains information about L3 cache eviction patterns that we reused in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KVM PoC to evict a function pointer.
  • https://xania.org/201602/bpu-part-one: Matt Godbolt blogged about reverse-engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 structure of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 branch predictor on Intel processors.
  • https://www.sophia.re/cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365sis.pdf: Sophia D'Antoine wrote a cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365sis that shows that opcode scheduling can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365oretically be used to transmit data between hyperthreads.
  • https://gruss.cc/files/kaiser.pdf: Daniel Gruss, Moritz Lipp, Michael Schwarz, Richard Fellner, Clémentine Maurice, and Stefan Mangard wrote a paper on mitigating microarchitectural issues caused by pagetable sharing between userspace and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel.
  • https://www.jilp.org/: This journal contains many articles on branch prediction.
  • http://blog.stuffedcow.net/2013/01/ivb-cache-replacement/: This blogpost by Henry Wong investigates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L3 cache replacement policy used by Intel's Ivy Bridge architecture.

References

[1] This initial report did not contain any information about variant 3. We had discussed whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r direct reads from kernel memory could work, but thought that it was unlikely. We later tested and reported variant 3 prior to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 publication of Anders Fogh's work at https://cyber.wtf/2017/07/28/negative-result-reading-kernel-memory-from-user-mode/.
[2] The precise model names are listed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 section "Tested Processors". The code for reproducing this is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 writeup_files.tar archive in our bugtracker, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 folders userland_test_x86 and userland_test_aarch64.
[3] The attacker-controlled offset used to perform an out-of-bounds access on an array by this PoC is a 32-bit value, limiting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 accessible addresses to a 4GiB window in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel heap area.
[4] This PoC won't work on CPUs with SMAP support; however, that is not a fundamental limitation.
[5] linux-image-4.9.0-3-amd64 at version 4.9.30-2+deb9u2 (available at http://snapshot.debian.org/archive/debian/20170701T224614Z/pool/main/l/linux/linux-image-4.9.0-3-amd64_4.9.30-2%2Bdeb9u2_amd64.deb, sha256 5f950b26aa7746d75ecb8508cc7dab19b3381c9451ee044cd2edfd6f5efff1f8, signed via Release.gpg, Release, Packages.xz); that was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current distro kernel version when I set up cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 machine. It is very unlikely that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PoC works with ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r kernel versions without changes; it contains a number of hardcoded addresses/offsets.
[6] The phone was running an Android build from May 2017.
[9] More than 215 mappings would be more efficient, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel places a hard cap of 216 on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of VMAs that a process can have.
[10] Intel's optimization manual states that "In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first implementation of HT Technology, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical execution resources are shared and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 architecture state is duplicated for each logical processor", so it would be plausible for predictor state to be shared. While predictor state could be tagged by logical core, that would likely reduce performance for multithreaded processes, so it doesn't seem likely.
[11] In case cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 history buffer was a bit bigger than we had measured, we added some margin - in particular because we had seen slightly different history buffer lengths in different experiments, and because 26 isn't a very round number.
[12] The basic idea comes from http://palms.ee.princeton.edu/system/files/SP_vfinal.pdf, section IV, although cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 authors of that paper still used hugepages.