This repository contains artifacts developed during a research project, as well as the code to perform the advanced TLB side channel of the paper "When Good Kernel Defenses Go Bad: Reliable and Stable Kernel Exploits via Defense-Amplified TLB Side-Channel Leaks", which got accepted at USENIX Security '25.
The paper shows how side-channel leakage in kernel defenses can be exploited to leak the locations of security-critical kernel objects, enabling reliable and stable attacks on the Linux kernel. By systematically analyzing 127 defenses, we show that enabling any of three specific defenses - strict memory permissions, kernel heap virtualization, or stack virtualization - exposes fine-grained TLB contention patterns. These patterns are then combined with kernel allocator massaging to perform location disclosure attacks, revealing the locations of kernel heap objects, page tables, and stacks.
The artifacts demonstrate the timing side-channel attack and the exploit techniques. For both, we provide a kernel module and programs to perform the experiments.
- For the timing side channel, we leak the location of kernel heap objects (i.e.,
pipe_buffer
,msg_msg
,cred
,file
, andseq_file
), page tables (all levels), and the kernel stack. While our side channel works on all Intel generations between the 8th and 14th, we recommend evaluating on Intel 13th generation, as we have mainly evaluated on this one. While our side channel works on Linux kernels between v5.15 and v6.8, we recommend evaluating on the Ubuntu generic kernel v6.8. - For the exploit techniques, we perform privilege escalation using the 3 techniques. Inherent to kernel exploitation, we tailor these techniques to the specific Ubuntu generic kernel v6.8.0-38, the required version to evaluate these techniques.
For evaluating the timing side channel, the experiments can be used in kernel exploitation of memory-corruption attacks, as they allow the location of kernel objects be leaked on Intel CPUs. This raises potential ethical concerns.
For evaluating the exploit techniques, the artifacts might result in destructive steps. While we introduce an exploit primitive via a kernel module and do not provide methods to compromise systems in the wild, the experiment using this primitive may cause system crashes. However, during our evaluation, we have not encountered a single system crash.
We provide the source code (github) for performing the timing side channel.
A Linux system running on an Intel CPU between 8th and 14th generation. However, we recommend running the evaluation on a 13th generation Intel, as this is what we have mainly evaluated on. We have observed a trend that newer Intel CPUs and better cooling tend to give more stable results.
While our disclosure attacks should generically work on Linux kernels, our experiments are tailored to Ubuntu Linux kernels between v5.15 to v6.8. As reference, we have mainly evaluated on the generic Ubuntu kernel v6.8.0-38 (and the kernel with CONFIG_SLAB_VIRTUAL
of v6.6 (patch)).
One part of the artifact evaluation is to insert a kernel module that requires root privileges. This module is required to obtain the ground truth of the kernel object's location as well as for providing the exploit primitive for the exploit techniques. We tested our kernel module on Ubuntu Linux downstream kernels v5.15, v6.5, and v6.8 and kernel v6.6. For other kernels that have different config files (or other downstream changes) our implemented module may not do what we intended. Specifically, in order to obtain the location of kernel objects, we redefined and reimplemented structures and functions. We did this because some functions used to access kernel data structures are implemented as inline functions, e.g., ipc_obtain_object_check
, which prevented us from calling these functions directly. Another reason is that some structs, e.g., msg_queue
, are defined in c files, which also prevents us from using these struct definitions.
While this artifact evaluation include experiments exploiting leakage for all defenses, we only recommend to reproduce experiments exploiting leakage from D1 and D3. This is because reproducing leakage from D2 requires a Linux kernel compiled with CONFIG_SLAB_VIRTUAL, i.e., the intended v6.6 used by Google's KernelCTF. We encountered driver crashes during boot due to incompatibilities, requiring additional engineering effort. However, all of our heap location leakage attacks should work directly by exploiting D2 when swapping the base address from the DPM to the virtual heap.
Due to the nature of kernel exploitation in general, our exploit techniques depend on the kernel version. Therefore, we only provide the end-to-end attack for the exact Ubuntu Linux kernel v6.8.0-38 (and the kernel with CONFIG_SLAB_VIRTUAL of v6.6). The exact version is needed, e.g., for the control-flow hijacking attack, as the ROP chain varies between versions. Similarly, the other two exploit techniques require internal version-dependent kernel information. Curically, all information can be obtained as an unprivileged user but requires engineering effort.
The installation required to perform artifact evaluation works as following:
- Clone our github repository (github) to
/repo/path
directory. - Change directory to
/repo/path
. - Select in
./lkm.c
eitherV5_15
,V6_5
,V6_6
, orV6_8
, depending on your running Ubuntu Linux kernel version. - Execute
make init
to build the kernel module and all experiments and insert the kernel module.
Before starting the experiments, determine the TLB hit thresholds on your CPU as follows. It is important to ensure that the background noise is as low as possible before starting this basic experiment, as described in Notes on Reusability.
- Change directory to
/repo/path/generic
. - Execute
./threshold_detection.elf
prints[+] detected thresholds: <THRESHOLD> <THRESHOLD2>
, whereTHRESHOLD
is the threshold for capturing 97 % of all hit timings of mapped addresses andTHRESHOLD2
is the threshold for the minimum timing of unmapped addresses. - Repeat this a few times and write the most consistent result to
THRESHOLD
andTHRESHOLD2
in./include/tlb_flush.h
and recompile withmake build
in/repo/path
.
Before running the experiments, please perform Set-Up and read Notes on Reusability.
How to:
Execute ./generic/dpm_leak.elf
.
Results: This experiment outputs the base address of the DPM.
How to:
Execute ./generic/vmalloc_leak.elf
.
Results:
This experiment outputs the base address of the virtual memory section used for vmalloc
.
How to:
Execute ./generic/vmemmap_leak.elf
.
Results:
This experiment outputs the base address of the virtual memory mapping vmemmap
.
How to:
Execute ./heap/msg_msg_leak.elf
.
Results:
This experiment outputs the page-aligned msg_msg
object location.
How to:
Execute ./heap/file_leak.elf
.
Results:
This experiment outputs the page-aligned file
object location.
How to:
Execute ./heap/seq_file_leak.elf
.
Results:
This experiment outputs the page-aligned seq_file
object location.
How to:
Execute ./heap/pipe_buffer_leak.elf
.
Results:
This experiment outputs the page-aligned pipe_buffer
object location.
How to:
Execute ./page-table/pt_leak.elf
, ./page-table/pmd_leak.elf
, or ./page-table/pud_leak.elf
.
Results: This experiment outputs the respective location of PT, PMD, and PUD.
How to:
Execute ./eval.sh
(in heap
, page-table
and stack
) and then ./print.py
.
Description:
The ./eval.sh
scripts performs between 20 to 100 execution of (E4-9) depending on the experiment, while ./print.py
prints a table which should closely resemble Table 1. As described in A.5, background activity should be minimized in this evaluation.
Results: This experiment outputs the content of Table 1 for D1 and D3.
How to:
Execute ./attacks/pipe_unlink.elf
.
Limitation: Works with Ubuntu kernel v6.8.0-38. Other versions will most likely lead to a program crash.
Results: Privilege escalation.
How to:
Execute ./attacks/dirty_page.elf
or ./attacks/advanced_slubstick.elf
.
Limitation:
Works with Ubuntu kernel v6.8.0-38 or the v6.6 intended to be used with CONFIG_SLAB_VIRTUAL
. Other versions will most likely lead to a program crash.
Results: Privilege escalation.
How to:
Execute ./attacks/stack_attack.elf
.
Limitation: Works with Ubuntu kernel v6.8.0-38. Other versions will most likely lead to a program crash.
Results: Privilege escalation.
How to:
Execute ./attacks/eval.sh
and then ./attacks/print.py
, both in attacks
.
Results: This experiment shows the success rate of the 3 exploit techniques.
As described in Section 6.2 Stress, the most dominant noise source is CPU frequency fluctuation. Hence, perform all experiments with as little background activity as possible to reproduce the paper's results. We even suggest to perform the experiments on an idle system with no other activity.