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 a2cdd64c6f915d969dfa21e23049ff4b3836b13d
parent 546a50cb8bb80775c71e7469f2a2891ac1fa1b24
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue,  7 Feb 2023 07:38:12 -0600

Add combined testcase based on exit codes

Diffstat:
M.gitignore | 1+
Mcachepc/cachepc.c | 1+
Mcachepc/kvm.c | 76++--------------------------------------------------------------------------
Atest/all | 11+++++++++++
Mtest/eviction.c | 17+++++++++++------
Mtest/kvm-eviction.c | 17+++++++++++++----
6 files changed, 39 insertions(+), 84 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -4,3 +4,4 @@ push.sh .cache linux-* compile_commands.json +logs diff --git a/cachepc/cachepc.c b/cachepc/cachepc.c @@ -162,6 +162,7 @@ cpc_save_msrmts(struct cpc_cl *head) do { if (cl->first) { BUG_ON(cl->set >= L1_SETS); + BUG_ON(cl->line != 0); if (cl->count > L1_ASSOC) { CPC_ERR("OOB count %llu for set %u\n", cl->count, cl->set); diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -124,10 +124,6 @@ static int cpc_apply_baseline_ioctl(void __user *arg_user); static int cpc_reset_tracking_ioctl(void __user *arg_user); static int cpc_track_mode_ioctl(void __user *arg_user); -// static int cpc_track_page_ioctl(void __user *arg_user); -// static int cpc_track_range_start_ioctl(void __user *arg_user); -// static int cpc_track_range_end_ioctl(void __user *arg_user); -// static int cpc_track_exec_cur_ioctl(void __user *arg_user); static int cpc_req_pause_ioctl(void __user *arg_user); @@ -220,14 +216,14 @@ cpc_single_eviction_test(void *p) if (count != 1 || cpc_msrmts[target] != 1) { CPC_ERR("Single eviction %i. test failed (%u vs %u)\n", n, count, 1); - if (arg) *arg = count; + if (arg) *arg = 1; break; } } if (n == TEST_REPEAT_MAX) { CPC_INFO("Single eviction test ok (%u vs %u)\n", count, 1); - if (arg) *arg = count; + if (arg) *arg = 0; } kfree(victim_ul); @@ -546,66 +542,6 @@ cpc_track_mode_ioctl(void __user *arg_user) return 0; } -// int -// cpc_track_page_ioctl(void __user *arg_user) -// { -// struct cpc_track_config cfg; -// struct kvm_vcpu *vcpu; -// -// if (!main_vm || !arg_user) return -EINVAL; -// -// if (copy_from_user(&cfg, arg_user, sizeof(cfg))) -// return -EFAULT; -// -// if (cfg.mode < 0 || cfg.mode >= KVM_PAGE_TRACK_MAX) -// return -EINVAL; -// -// BUG_ON(xa_empty(&main_vm->vcpu_array)); -// vcpu = xa_load(&main_vm->vcpu_array, 0); -// if (!cpc_track_single(vcpu, cfg.gfn, cfg.mode)) -// return -EFAULT; -// -// return 0; -// } -// -// int -// cpc_track_range_start_ioctl(void __user *arg_user) -// { -// if (!arg_user) return -EINVAL; -// -// if (copy_from_user(&cpc_track_start_gfn, arg_user, sizeof(uint64_t))) -// return -EFAULT; -// -// return 0; -// } -// -// int -// cpc_track_range_end_ioctl(void __user *arg_user) -// { -// if (!arg_user) return -EINVAL; -// -// if (copy_from_user(&cpc_track_end_gfn, arg_user, sizeof(uint64_t))) -// return -EFAULT; -// -// return 0; -// } -// -// int -// cpc_track_exec_cur_ioctl(void __user *arg_user) -// { -// struct cpc_fault *fault; -// -// if (!arg_user) return -EINVAL; -// -// fault = list_first_entry(&cpc_faults, struct cpc_fault, list); -// if (!fault) return -EFAULT; -// -// if (copy_to_user(arg_user, &fault->gfn, sizeof(uint64_t))) -// return -EFAULT; -// -// return 0; -// } - int cpc_req_pause_ioctl(void __user *arg_user) { @@ -655,14 +591,6 @@ cpc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) return cpc_batch_events_ioctl(arg_user); case KVM_CPC_READ_BATCH: return cpc_read_batch_ioctl(arg_user); - // case KVM_CPC_TRACK_PAGE: - // return cpc_track_page_ioctl(arg_user); - // case KVM_CPC_TRACK_RANGE_START: - // return cpc_track_range_start_ioctl(arg_user); - // case KVM_CPC_TRACK_RANGE_END: - // return cpc_track_range_end_ioctl(arg_user); - // case KVM_CPC_TRACK_EXEC_CUR: - // return cpc_track_exec_cur_ioctl(arg_user); case KVM_CPC_VM_REQ_PAUSE: return cpc_req_pause_ioctl(arg_user); default: diff --git a/test/all b/test/all @@ -0,0 +1,11 @@ +#!/bin/bash + +mkdir -p logs + +set -ex + +./test/eviction &> logs/eviction +./test/kvm-eviction &> logs/kvm-eviction +./test/kvm-pagestep &> logs/kvm-pagestep +./test/kvm-step &> logs/kvm-step +./test/kvm-targetstep &> logs/kvm-targetstep diff --git a/test/eviction.c b/test/eviction.c @@ -14,7 +14,7 @@ int main(int argc, const char **argv) { uint8_t counts[L1_SETS]; - uint32_t set; + uint32_t arg, set; int fd, ret; fd = open("/dev/kvm", O_RDONLY); @@ -22,18 +22,23 @@ main(int argc, const char **argv) set = 48; if (argc > 1) set = atoi(argv[1]); - if (set >= L1_SETS) - errx(1, "set out-of-bounds"); + if (set >= L1_SETS) errx(1, "set out-of-bounds"); - ret = ioctl(fd, KVM_CPC_TEST_EVICTION, &set); - if (ret == -1) err(1, "ioctl KVM_CPC_TEST_EVICTION"); + ret = ioctl(fd, KVM_CPC_RESET, &arg); + if (ret == -1) err(1, "KVM_CPC_RESET"); + + arg = set; + ret = ioctl(fd, KVM_CPC_TEST_EVICTION, &arg); + if (ret == -1) err(1, "KVM_CPC_TEST_EVICTION"); ret = ioctl(fd, KVM_CPC_READ_COUNTS, counts); - if (ret == -1) err(1, "ioctl KVM_CPC_READ_COUNTS"); + if (ret == -1) err(1, "KVM_CPC_READ_COUNTS"); print_counts(counts); printf("\n"); print_counts_raw(counts); close(fd); + + return arg; } diff --git a/test/kvm-eviction.c b/test/kvm-eviction.c @@ -43,7 +43,7 @@ main(int argc, const char **argv) uint8_t counts[2][SAMPLE_COUNT][L1_SETS]; uint8_t baseline[L1_SETS]; struct cpc_track_cfg cfg; - int i, k, ret; + int i, k, ret, exitcode; vmtype = "kvm"; if (argc > 1) vmtype = argv[1]; @@ -126,26 +126,35 @@ main(int argc, const char **argv) } /* check for measurment errors */ + exitcode = 0; for (i = 0; i < SAMPLE_COUNT; i++) { for (k = 0; k < L1_SETS; k++) { - if (counts[WITH][i][k] + baseline[k] > L1_ASSOC) + if (counts[WITH][i][k] + baseline[k] > L1_ASSOC) { warnx("sample %i: With count OOB for set %i (=%i)", i, k, counts[WITH][i][k] + baseline[k]); + exitcode = 1; + } - if (counts[WITHOUT][i][k] + baseline[k] > L1_ASSOC) + if (counts[WITHOUT][i][k] + baseline[k] > L1_ASSOC) { warnx("sample %i: Without count OOB for set %i (=%i)", i, k, counts[WITHOUT][i][k] + baseline[k]); + exitcode = 1; + } } - if (!counts[WITH][i][TARGET_SET]) + if (!counts[WITH][i][TARGET_SET]) { warnx("sample %i: Missing eviction in target set %i (=%i,%i)", i, TARGET_SET, counts[WITH][i][TARGET_SET], counts[WITH][i][TARGET_SET] + baseline[TARGET_SET]); + exitcode = 1; + } } vm_deinit(&vms[WITH]); vm_deinit(&vms[WITHOUT]); kvm_setup_deinit(); + + return exitcode; }