Skip to content

Instantly share code, notes, and snippets.

@kotarou3
Created September 1, 2015 10:38
Show Gist options
  • Save kotarou3/5c9b44b8c6a3eaa8cda5 to your computer and use it in GitHub Desktop.
Save kotarou3/5c9b44b8c6a3eaa8cda5 to your computer and use it in GitHub Desktop.
Scripted performance counting for side channel attacks
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <linux/perf_event.h>
#include <sched.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
static inline uint64_t readu64(int fd) {
uint64_t result;
syscall(__NR_read, fd, &result, sizeof(result));
return result;
}
int main(int argc, char** argv) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <args ...>\n", argv[0]);
return 1;
}
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(0, &set);
sched_setaffinity(0, sizeof(set), &set);
struct perf_event_attr attr;
memset(&attr, 0, sizeof(struct perf_event_attr));
attr.type = PERF_TYPE_HARDWARE;
attr.size = sizeof(struct perf_event_attr);
attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
attr.exclude_kernel = 1;
attr.exclude_hv = 1;
attr.exclude_idle = 1;
int perfFd = syscall(__NR_perf_event_open, &attr, 0, 0, -1, 0);
if (perfFd < 0) {
perror("perf_event_open");
return 1;
}
int pipes[2];
pipe(pipes);
dup2(pipes[0], 0);
for (size_t n = 0; n < 100; ++n) {
if (write(pipes[1], "testing123\n", 12) != 12) {
perror("write");
return 1;
}
uint64_t start = readu64(perfFd);
pid_t pid = vfork();
if (pid == 0) {
execve(argv[1], &argv[1], 0);
perror("execve");
_exit(1);
}
int status;
waitpid(pid, &status, 0);
uint64_t delta = readu64(perfFd) - start;
fprintf(stderr, "%llu\n", delta);
if (!WIFEXITED(status)) {
fprintf(stderr, "Child did not exit\n");
return 1;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment