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

util.c (4306B)


      1#define _GNU_SOURCE
      2
      3#include "test/util.h"
      4
      5#include <sys/types.h>
      6#include <sys/mman.h>
      7#include <dirent.h>
      8#include <pthread.h>
      9#include <err.h>
     10#include <sched.h>
     11#include <string.h>
     12#include <stdio.h>
     13#include <stdint.h>
     14#include <stdlib.h>
     15
     16void
     17hexdump(void *data, int len)
     18{
     19	int i;
     20
     21	for (i = 0; i < len; i++) {
     22		if (i % 16 == 0 && i)
     23			printf("\n");
     24		printf("%02X ", *(uint8_t *)(data + i));
     25	}
     26	printf("\n");
     27}
     28
     29bool
     30pin_process(pid_t pid, int cpu, bool assert)
     31{
     32	cpu_set_t cpuset;
     33	int ret;
     34
     35	CPU_ZERO(&cpuset);
     36	CPU_SET(cpu, &cpuset);
     37	ret = sched_setaffinity(pid, sizeof(cpu_set_t), &cpuset);
     38	if (ret == -1) {
     39		if (assert) err(1, "sched_setaffinity");
     40		return false;
     41	}
     42
     43	return true;
     44}
     45
     46int
     47read_stat_core(pid_t pid)
     48{
     49	char path[256];
     50	char line[2048];
     51	FILE *file;
     52	char *p;
     53	int i, cpu;
     54
     55	snprintf(path, sizeof(path), "/proc/%u/stat", pid);
     56	file = fopen(path, "r");
     57	if (!file) return -1;
     58
     59	if (!fgets(line, sizeof(line), file))
     60		err(1, "read stat");
     61
     62	p = line;
     63	for (i = 0; i < 38 && (p = strchr(p, ' ')); i++)
     64		p += 1;
     65
     66	if (!p) errx(1, "stat format");
     67	cpu = atoi(p);
     68
     69	fclose(file);
     70
     71	return cpu;
     72}
     73
     74pid_t
     75pgrep(const char *bin)
     76{
     77	char path[PATH_MAX];
     78	char buf[PATH_MAX];
     79	struct dirent *ent;
     80	char *cmp;
     81	FILE *f;
     82	DIR *dir;
     83	pid_t pid;
     84
     85	dir = opendir("/proc");
     86	if (!dir) err(1, "opendir");
     87
     88	pid = 0;
     89	while (!pid && (ent = readdir(dir))) {
     90		snprintf(path, sizeof(path), "/proc/%s/cmdline", ent->d_name);
     91		f = fopen(path, "rb");
     92		if (!f) continue;
     93		memset(buf, 0, sizeof(buf));
     94		fread(buf, 1, sizeof(buf), f);
     95		if ((cmp = strrchr(buf, '/')))
     96			cmp += 1;
     97		else
     98			cmp = buf;
     99		if (!strcmp(cmp, bin))
    100			pid = atoi(ent->d_name);
    101		fclose(f);
    102	}
    103
    104	closedir(dir);
    105
    106	return pid;
    107}
    108
    109void
    110print_counts(uint8_t *counts)
    111{
    112	int i;
    113
    114	for (i = 0; i < 64; i++) {
    115		if (i % 16 == 0 && i)
    116			printf("\n");
    117		if (counts[i] == 1)
    118			printf("\x1b[38;5;88m");
    119		else if (counts[i] > 1)
    120			printf("\x1b[38;5;196m");
    121		printf("%2i ", i);
    122		if (counts[i] > 0)
    123			printf("\x1b[0m");
    124	}
    125	printf("\n");
    126}
    127
    128void
    129print_counts_raw(uint8_t *counts)
    130{
    131	int i;
    132
    133	for (i = 0; i < 64; i++) {
    134		if (i % 16 == 0 && i)
    135			printf("\n");
    136		if (counts[i] == 1)
    137			printf("\x1b[38;5;88m");
    138		else if (counts[i] > 1)
    139			printf("\x1b[38;5;196m");
    140		printf("%02X ", (uint8_t) counts[i]);
    141		if (counts[i] > 0)
    142			printf("\x1b[0m");
    143	}
    144	printf("\n");
    145}
    146
    147struct ipc *
    148ipc_alloc(void)
    149{
    150	pthread_mutexattr_t mutex_attr;
    151	pthread_condattr_t cond_attr;
    152	struct ipc *ipc;
    153
    154	pthread_condattr_init(&cond_attr);
    155	pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
    156
    157	pthread_mutexattr_init(&mutex_attr);
    158	pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
    159
    160	ipc = mmap(NULL, sizeof(struct ipc), PROT_READ | PROT_WRITE,
    161		MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    162	if (ipc == MAP_FAILED) err(1, "mmap");
    163
    164	pthread_mutex_init(&ipc->lock, &mutex_attr);
    165
    166	pthread_cond_init(&ipc->sig_parent, &cond_attr);
    167	ipc->has_sig_parent = false;
    168
    169	pthread_cond_init(&ipc->sig_child, &cond_attr);
    170	ipc->has_sig_child = false;
    171
    172	ipc->init = true;
    173
    174	return ipc;
    175}
    176
    177void
    178ipc_free(struct ipc *ipc)
    179{
    180	if (ipc->init) {
    181		pthread_mutex_destroy(&ipc->lock);
    182		pthread_cond_destroy(&ipc->sig_parent);
    183		pthread_cond_destroy(&ipc->sig_child);
    184		ipc->init = false;
    185	}
    186	munmap(ipc, sizeof(ipc));
    187}
    188
    189void
    190ipc_signal_parent(struct ipc *ipc)
    191{
    192	if (!ipc->init) errx(1, "ipc deinit");
    193	pthread_mutex_lock(&ipc->lock);
    194	if (!ipc->has_sig_child)
    195		pthread_cond_signal(&ipc->sig_child);
    196	ipc->has_sig_child = true;
    197	pthread_mutex_unlock(&ipc->lock);
    198}
    199
    200void
    201ipc_wait_child(struct ipc *ipc)
    202{
    203	if (!ipc->init) errx(1, "ipc deinit");
    204	pthread_mutex_lock(&ipc->lock);
    205	while (!ipc->has_sig_child)
    206		pthread_cond_wait(&ipc->sig_child, &ipc->lock);
    207	ipc->has_sig_child = false;
    208	pthread_mutex_unlock(&ipc->lock);
    209}
    210
    211void
    212ipc_signal_child(struct ipc *ipc)
    213{
    214	if (!ipc->init) errx(1, "ipc deinit");
    215	pthread_mutex_lock(&ipc->lock);
    216	if (!ipc->has_sig_parent)
    217		pthread_cond_signal(&ipc->sig_parent);
    218	ipc->has_sig_parent = true;
    219	pthread_mutex_unlock(&ipc->lock);
    220}
    221
    222void
    223ipc_wait_parent(struct ipc *ipc)
    224{
    225	if (!ipc->init) errx(1, "ipc deinit");
    226	pthread_mutex_lock(&ipc->lock);
    227	while (!ipc->has_sig_parent)
    228		pthread_cond_wait(&ipc->sig_parent, &ipc->lock);
    229	ipc->has_sig_parent = false;
    230	pthread_mutex_unlock(&ipc->lock);
    231}
    232