libkdump is a library to exploit the Meltdown bug. It allows to easily read kernel memory and physical memory on affected CPUs.
libkdump was developed for the paper
- Meltdown by Lipp, Schwarz, Gruss, Prescher, Haas, Mangard, Kocher, Genkin, Yarom, and Hamburg
and was used to run several experiments and evaluations.
libkdump supports a wide range of CPUs by automatically adapting most parameters to the current execution environment. libkdump was tested on Ubuntu 16.04.3, both with an Intel Core i7-6700K and an Intel Xeon E5-2650 v4, but it should work on every Linux which does not have KPTI enabled.
The library is shipped with a Makefile and can be compiled by running:
make
This produces both a shared library (libkdump.so
) and a static library (libkdump.a
).
libkdump does not have any dependencies.
libkdump can be installed system by running
sudo make install
and uninstalled by running
sudo make uninstall
This section gives a short overview of how to use libkdump. For a complete documentation, please refer to the source code and the demo applications.
To use libkdump, include the libkdump.h
header and initialize libkdump using libkdump_init
. When done, call libkdump_cleanup
to revert everything to the way it was before using libkdump.
#include "libkdump.h"
int main() {
// initialize libkdump
if(libkdump_init(libkdump_auto_config) != 0) {
return -1;
}
// use libkdump...
// done, cleanup everything
if(libkdump_cleanup() != 0) {
return -1;
}
return 0;
}
Compile and link with libkdump (static)
gcc example.c -L. -static -lkdump -pthread
or as shared library
gcc example.c -lkdump
libkdump provides libkdump_read
as a simple function to read the content of any virtual address. This is independent of whether the virtual address is accessible (user space address) or inaccessible (kernel space address).
size_t addr = 0xfffffffc00022a0ull;
// read the (kernel) address
int value = libkdump_read(addr);
// output result
printf("%c\n", value);
To read physical memory, libkdump relies on the direct physical map of Linux which is located at 0xffff 8800 0000 0000
if KASLR is disabled.
If KASLR is disabled (e.g., due to an older kernel version, or the nokaslr
kernel command line), reading physical memory is as simple as calling libkdump_phys_to_virt
on the physical address. The function returns a virtual address for the physical address, which can then be used with libkdump_read
.
If KASLR is enabled, you have to provide the randomized offset of the direct physical map to libkdump in the initialization (see Example (KASLR)). As the offset does only change with a reboot, it is sufficient to brute-force the offset once (see the kaslr demo or the paper). This takes usually only a few seconds.
// read memory at physical offset 1GB
size_t phys_addr = 1024 * 1024 * 1024; // 1GB
// convert to virtual address
size_t vaddr = libkdump_phys_to_virt(phys_addr);
// read the virtual address
int value = libkdump_read(vaddr);
// output result
printf("%c\n", value);
// custom config for libkdump
libkdump_config_t config;
// set sane defaults
config = libkdump_get_autoconfig();
// change address of direct physical map
config.physical_offset = 0xffff98a000000000ull;
// initialize libkdump with custom config
if(libkdump_init(config) != 0) {
return -1;
}
// read memory at physical offset 1GB
size_t phys_addr = 1024 * 1024 * 1024; // 1GB
// convert to virtual address
size_t vaddr = libkdump_phys_to_virt(phys_addr);
// read the virtual address
int value = libkdump_read(vaddr);
// output result
printf("%c\n", value);
In some cases, the auto configuration of libkdump might not be sufficient (e.g., in the case of KASLR). Thus, libkdump allows to either specify all configuration options manually, or adapt all options after the auto configuration. Furthermore, libkdump also has some compile-time configurations which cannot be changed during runtime.
Most options of libkdump can be changed at runtime. All these options are configurable via the libkdump_config_t
struct that is passed to the libkdump_init
function.
The recommended way to change any option is to first get the libkdump auto configuration, and then overwrite specific options.
// custom config for libkdump
libkdump_config_t config;
// get auto config from libkdump
config = libkdump_get_autoconfig();
// change any property, e.g., direct-physical map offset
config.physical_offset = 0xffff98a000000000ull;
// initialize libkdump with custom config
if(libkdump_init(config) != 0) {
return -1;
}
The following options can be configured:
cache_miss_threshold
: Cache miss threshold in cycles for Flush Reload. If a memory access is faster than this, it is considered a cache hit, if it is slower, it is considered a cache miss (i.e., a memory access) (default: auto detected).fault_handling
: How exceptions are handled. Either via fault handling with signal handlers (SIGNAL_HANDLER
) or via fault suppression using Intel TSX (TSX
). Note that TSX can only be used if it is supported (default: TSX if available).measurements
: The number of measurements to perform for one address. Majority vote is used to determine the most likely value afterwards (default: 3).accept_after
: How many measurements must read the same character, even if this character won the majority vote (default: 1).load_threads
: Number of threads which are started to increase the chance of reading from inaccessible addresses (default: 1)load_type
: The function which is executed by the load threads. One ofNOP
(just an endless loop),YIELD
(continuously switch between user space and kernel space), orIO
(continuously issue interrupts by syncing the file system) (default: NOP).retries
: Number of Meltdown retries for an address, i.e., how often Meltdown should retry when reading a zero (default: 10000).physical_offset
: The virtual address of the direct-physical map. If KASLR is not enabled, this is 0xffff880000000000, otherwise it has to be adapted as this cannot be automatically detected (default: 0xffff880000000000).
libkdump has some options which cannot be configured at runtime, but have to be configured at compile time. This is done using macros when compiling libkdump (e.g., by adding them in the Makefile).
NO_TSX
: Do not compile TSX support (e.g., if the compiler does not support the TSX instructions).FORCE_TSX
: If the auto detection does not work, but the target system has TSX, this compile-time option enforces TSX. However, if TSX is not available, the program will crash.USE_RDTSCP
: Userdtscp
instead ofrdtsc
to measure time. Might be necessary on virtual machines, ifrdtsc
is emulated. However, ifrdtscp
is not available, the program will crash.MELTDOWN
: The variant of Meltdown to use. One ofmeltdown_nonull
(default, as described in the paper),meltdown
(with an additional NULL pointer access, increases the success probability on some newer CPUs), ormeltdown_fast
(without retry logic, might work better on slower CPUs).