cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

syscall_tp_user.c (3269B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright (c) 2017 Facebook
      3 */
      4#include <stdio.h>
      5#include <unistd.h>
      6#include <fcntl.h>
      7#include <stdlib.h>
      8#include <string.h>
      9#include <linux/perf_event.h>
     10#include <errno.h>
     11#include <bpf/libbpf.h>
     12#include <bpf/bpf.h>
     13
     14/* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*.
     15 * This requires kernel CONFIG_FTRACE_SYSCALLS to be set.
     16 */
     17
     18static void usage(const char *cmd)
     19{
     20	printf("USAGE: %s [-i num_progs] [-h]\n", cmd);
     21	printf("       -i num_progs      # number of progs of the test\n");
     22	printf("       -h                # help\n");
     23}
     24
     25static void verify_map(int map_id)
     26{
     27	__u32 key = 0;
     28	__u32 val;
     29
     30	if (bpf_map_lookup_elem(map_id, &key, &val) != 0) {
     31		fprintf(stderr, "map_lookup failed: %s\n", strerror(errno));
     32		return;
     33	}
     34	if (val == 0) {
     35		fprintf(stderr, "failed: map #%d returns value 0\n", map_id);
     36		return;
     37	}
     38
     39	printf("verify map:%d val: %d\n", map_id, val);
     40
     41	val = 0;
     42	if (bpf_map_update_elem(map_id, &key, &val, BPF_ANY) != 0) {
     43		fprintf(stderr, "map_update failed: %s\n", strerror(errno));
     44		return;
     45	}
     46}
     47
     48static int test(char *filename, int num_progs)
     49{
     50	int map0_fds[num_progs], map1_fds[num_progs], fd, i, j = 0;
     51	struct bpf_link *links[num_progs * 4];
     52	struct bpf_object *objs[num_progs];
     53	struct bpf_program *prog;
     54
     55	for (i = 0; i < num_progs; i++) {
     56		objs[i] = bpf_object__open_file(filename, NULL);
     57		if (libbpf_get_error(objs[i])) {
     58			fprintf(stderr, "opening BPF object file failed\n");
     59			objs[i] = NULL;
     60			goto cleanup;
     61		}
     62
     63		/* load BPF program */
     64		if (bpf_object__load(objs[i])) {
     65			fprintf(stderr, "loading BPF object file failed\n");
     66			goto cleanup;
     67		}
     68
     69		map0_fds[i] = bpf_object__find_map_fd_by_name(objs[i],
     70							      "enter_open_map");
     71		map1_fds[i] = bpf_object__find_map_fd_by_name(objs[i],
     72							      "exit_open_map");
     73		if (map0_fds[i] < 0 || map1_fds[i] < 0) {
     74			fprintf(stderr, "finding a map in obj file failed\n");
     75			goto cleanup;
     76		}
     77
     78		bpf_object__for_each_program(prog, objs[i]) {
     79			links[j] = bpf_program__attach(prog);
     80			if (libbpf_get_error(links[j])) {
     81				fprintf(stderr, "bpf_program__attach failed\n");
     82				links[j] = NULL;
     83				goto cleanup;
     84			}
     85			j++;
     86		}
     87		printf("prog #%d: map ids %d %d\n", i, map0_fds[i], map1_fds[i]);
     88	}
     89
     90	/* current load_bpf_file has perf_event_open default pid = -1
     91	 * and cpu = 0, which permits attached bpf execution on
     92	 * all cpus for all pid's. bpf program execution ignores
     93	 * cpu affinity.
     94	 */
     95	/* trigger some "open" operations */
     96	fd = open(filename, O_RDONLY);
     97	if (fd < 0) {
     98		fprintf(stderr, "open failed: %s\n", strerror(errno));
     99		return 1;
    100	}
    101	close(fd);
    102
    103	/* verify the map */
    104	for (i = 0; i < num_progs; i++) {
    105		verify_map(map0_fds[i]);
    106		verify_map(map1_fds[i]);
    107	}
    108
    109cleanup:
    110	for (j--; j >= 0; j--)
    111		bpf_link__destroy(links[j]);
    112
    113	for (i--; i >= 0; i--)
    114		bpf_object__close(objs[i]);
    115	return 0;
    116}
    117
    118int main(int argc, char **argv)
    119{
    120	int opt, num_progs = 1;
    121	char filename[256];
    122
    123	while ((opt = getopt(argc, argv, "i:h")) != -1) {
    124		switch (opt) {
    125		case 'i':
    126			num_progs = atoi(optarg);
    127			break;
    128		case 'h':
    129		default:
    130			usage(argv[0]);
    131			return 0;
    132		}
    133	}
    134
    135	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
    136
    137	return test(filename, num_progs);
    138}