cachepc

Prime+Probe cache-based side-channel attack on AMD SEV-SNP protected virtual machines
git clone https://git.sinitax.com/sinitax/cachepc
Log | Files | Refs | Submodules | README | sfeed.txt

commit da76c11f2059a8696a3df41844d49f82e6988843
parent 58d8565f015f9e06e1e51a0fe4654b966b2c27c0
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed,  5 Oct 2022 15:33:22 +0200

Fix uapi types and expose KVM_TRACK enum

Diffstat:
MMakefile | 2+-
Mcachepc/uapi.h | 7++++---
Mpatch.diff | 35++++++++++++++++-------------------
Msevstep/kvm.h | 2+-
Msevstep/uapi.h | 77+++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mtest/kvm.c | 6------
Atest/sevstep | 0
Mtest/sevstep.c | 4+++-
8 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/Makefile b/Makefile @@ -21,7 +21,7 @@ load: sudo insmod $(LINUX)/arch/x86/kvm/kvm.ko sudo insmod $(LINUX)/arch/x86/kvm/kvm-amd.ko -test/%: test/%.c cachepc/cachepc_user.h +test/%: test/%.c cachepc/uapi.h sevstep/uapi.h clang -o $@ $< -fsanitize=address -I . -Wunused-variable diff --git a/cachepc/uapi.h b/cachepc/uapi.h @@ -1,8 +1,9 @@ #pragma once +#include <linux/types.h> #include <linux/ioctl.h> #define CACHEPC_IOCTL_MAGIC 0xBF -#define CACHEPC_IOCTL_TEST_ACCESS _IOWR(CACHEPC_IOCTL_MAGIC, 0, uint32_t) -#define CACHEPC_IOCTL_TEST_EVICTION _IOWR(CACHEPC_IOCTL_MAGIC, 1, uint32_t) -#define CACHEPC_IOCTL_INIT_PMC _IOW(CACHEPC_IOCTL_MAGIC, 2, uint32_t) +#define CACHEPC_IOCTL_TEST_ACCESS _IOWR(CACHEPC_IOCTL_MAGIC, 0, __u32) +#define CACHEPC_IOCTL_TEST_EVICTION _IOWR(CACHEPC_IOCTL_MAGIC, 1, __u32) +#define CACHEPC_IOCTL_INIT_PMC _IOW(CACHEPC_IOCTL_MAGIC, 2, __u32) diff --git a/patch.diff b/patch.diff @@ -1,39 +1,34 @@ diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h -index eb186bc57f6a..cefc1589e398 100644 +index eb186bc57f6a..3f767a27045e 100644 --- a/arch/x86/include/asm/kvm_page_track.h +++ b/arch/x86/include/asm/kvm_page_track.h -@@ -2,8 +2,14 @@ +@@ -2,10 +2,9 @@ #ifndef _ASM_X86_KVM_PAGE_TRACK_H #define _ASM_X86_KVM_PAGE_TRACK_H +-enum kvm_page_track_mode { +- KVM_PAGE_TRACK_WRITE, +- KVM_PAGE_TRACK_MAX, +-}; +#include<linux/srcu.h> + - enum kvm_page_track_mode { - KVM_PAGE_TRACK_WRITE, -+ KVM_PAGE_TRACK_ACCESS, -+ KVM_PAGE_TRACK_RESET_ACCESSED, //TODO: hacky, as this is not really for page tracking -+ KVM_PAGE_TRACK_EXEC, -+ KVM_PAGE_TRACK_RESET_EXEC, - KVM_PAGE_TRACK_MAX, - }; ++#include "../../kvm/sevstep/uapi.h" + /* + * The notifier represented by @kvm_page_track_notifier_node is linked into diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile -index 30f244b64523..7992f8cce838 100644 +index 30f244b64523..ddfd48fbd8ca 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile -@@ -1,8 +1,10 @@ +@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -ccflags-y += -I $(srctree)/arch/x86/kvm +ccflags-y += -I $(srctree)/arch/x86/kvm -O2 ccflags-$(CONFIG_KVM_WERROR) += -Werror -+KBUILD_EXTRA_SYMBOLS := ../../../drivers/crypto/ccp/Module.symvers -+ ifeq ($(CONFIG_FRAME_POINTER),y) - OBJECT_FILES_NON_STANDARD_vmenter.o := y - endif -@@ -11,8 +13,9 @@ include $(srctree)/virt/kvm/Makefile.kvm +@@ -11,8 +11,9 @@ include $(srctree)/virt/kvm/Makefile.kvm kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \ @@ -45,7 +40,7 @@ index 30f244b64523..7992f8cce838 100644 ifdef CONFIG_HYPERV kvm-y += kvm_onhyperv.o -@@ -25,7 +28,8 @@ kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ +@@ -25,7 +26,8 @@ kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ vmx/evmcs.o vmx/nested.o vmx/posted_intr.o kvm-intel-$(CONFIG_X86_SGX_KVM) += vmx/sgx.o @@ -400,7 +395,9 @@ index d9adf79124f9..1809b79cb6cd 100644 #include "trace.h" diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c -index e089fbf9017f..7899e1efe852 100644 +old mode 100644 +new mode 100755 +index e089fbf9017f..7899e1efe852 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -87,7 +87,7 @@ static void *sev_init_ex_buffer; diff --git a/sevstep/kvm.h b/sevstep/kvm.h @@ -1,4 +1,4 @@ #pragma once -#include "sev-step.h" +#include "sevstep.h" #include "uapi.h" diff --git a/sevstep/uapi.h b/sevstep/uapi.h @@ -12,75 +12,84 @@ #define KVM_USPT_RESET _IO(KVMIO, 0x26) #define KVM_USPT_TRACK_ALL _IOWR(KVMIO, 0x27, track_all_pages_t) #define KVM_USPT_UNTRACK_ALL _IOWR(KVMIO, 0x28, track_all_pages_t) -#define KVM_USPT_SETUP_RETINSTR_PERF _IOWR(KVMIO, 0x30,retired_instr_perf_config_t) -#define KVM_USPT_READ_RETINSTR_PERF _IOWR(KVMIO,0x31, retired_instr_perf_t) -#define KVM_USPT_BATCH_TRACK_START _IOWR(KVMIO,0x32,batch_track_config_t) -#define KVM_USPT_BATCH_TRACK_STOP _IOWR(KVMIO,0x33,batch_track_stop_and_get_t) -#define KVM_USPT_BATCH_TRACK_EVENT_COUNT _IOWR(KVMIO,0x34,batch_track_event_count_t) +#define KVM_USPT_SETUP_RETINSTR_PERF _IOWR(KVMIO, 0x30, retired_instr_perf_config_t) +#define KVM_USPT_READ_RETINSTR_PERF _IOWR(KVMIO, 0x31, retired_instr_perf_t) +#define KVM_USPT_BATCH_TRACK_START _IOWR(KVMIO, 0x32, batch_track_config_t) +#define KVM_USPT_BATCH_TRACK_STOP _IOWR(KVMIO, 0x33, batch_track_stop_and_get_t) +#define KVM_USPT_BATCH_TRACK_EVENT_COUNT _IOWR(KVMIO, 0x34, batch_track_event_count_t) #define KVM_USPT_POLL_EVENT_NO_EVENT 1000 #define KVM_USPT_POLL_EVENT_GOT_EVENT 0 +enum kvm_page_track_mode { + KVM_PAGE_TRACK_WRITE, + KVM_PAGE_TRACK_ACCESS, + KVM_PAGE_TRACK_RESET_ACCESSED, + KVM_PAGE_TRACK_EXEC, + KVM_PAGE_TRACK_RESET_EXEC, + KVM_PAGE_TRACK_MAX, +}; + typedef struct { - uint64_t id; // filled automatically - uint64_t faulted_gpa; - uint32_t error_code; - bool have_rip_info; - uint64_t rip; - uint64_t ns_timestamp; - bool have_retired_instructions; - uint64_t retired_instructions; + __u64 id; // filled automatically + __u64 faulted_gpa; + __u32 error_code; + __u8 have_rip_info; + __u64 rip; + __u64 ns_timestamp; + __u8 have_retired_instructions; + __u64 retired_instructions; } page_fault_event_t; typedef struct { - int tracking_type; - uint64_t expected_events; - int perf_cpu; - bool retrack; + __s32 tracking_type; + __u64 expected_events; + __s32 perf_cpu; + __u8 retrack; } batch_track_config_t; typedef struct { - uint64_t event_count; + __u64 event_count; } batch_track_event_count_t; typedef struct { page_fault_event_t* out_buf; - uint64_t len; - bool error_during_batch; + __u64 len; + __u8 error_during_batch; } batch_track_stop_and_get_t; typedef struct { - int cpu; // cpu on which we want to read the counter - uint64_t retired_instruction_count; // result param + __s32 cpu; // cpu on which we want to read the counter + __u64 retired_instruction_count; // result param } retired_instr_perf_t; typedef struct { - int cpu; // cpu on which counter should be programmed + __s32 cpu; // cpu on which counter should be programmed } retired_instr_perf_config_t; typedef struct { - uint64_t gpa; - uint64_t len; - bool decrypt_with_host_key; - int wbinvd_cpu; // -1: do not flush; else logical cpu on which we flush - void* output_buffer; + __u64 gpa; + __u64 len; + __u8 decrypt_with_host_key; + __s32 wbinvd_cpu; // -1: do not flush; else logical cpu on which we flush + __u64 output_buffer; } read_guest_memory_t; typedef struct { - int pid; - bool get_rip; + __s32 pid; + __u8 get_rip; } userspace_ctx_t; typedef struct { - uint64_t id; + __u64 id; } ack_event_t; typedef struct { - uint64_t gpa; - int track_mode; + __u64 gpa; + __s32 track_mode; } track_page_param_t; typedef struct { - int track_mode; + __s32 track_mode; } track_all_pages_t; diff --git a/test/kvm.c b/test/kvm.c @@ -46,12 +46,6 @@ extern uint8_t __stop_guest_with[]; extern uint8_t __start_guest_without[]; extern uint8_t __stop_guest_without[]; -static bool ready = false; -static bool processed = false; - -static ssize_t sysret; -static pid_t victim_pid; - static struct kvm kvm; static struct kvm_run *kvm_run; diff --git a/test/sevstep b/test/sevstep Binary files differ. diff --git a/test/sevstep.c b/test/sevstep.c @@ -4,6 +4,8 @@ #include <sys/ioctl.h> #include <err.h> +#include <unistd.h> +#include <fcntl.h> #include <stdlib.h> #include <stdio.h> @@ -13,7 +15,7 @@ main(int argc, const char **argv) track_all_pages_t tracking; int ret, fd; - fd = open("/proc/cachepc"); + fd = open("/proc/cachepc", O_RDONLY); if (!fd) err(1, "open"); tracking.track_mode = KVM_PAGE_TRACK_ACCESS;