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

get_cgroup_id_user.c (3838B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2018 Facebook
      3
      4#include <stdio.h>
      5#include <stdlib.h>
      6#include <string.h>
      7#include <errno.h>
      8#include <fcntl.h>
      9#include <syscall.h>
     10#include <unistd.h>
     11#include <linux/perf_event.h>
     12#include <sys/ioctl.h>
     13#include <sys/time.h>
     14#include <sys/types.h>
     15#include <sys/stat.h>
     16
     17#include <linux/bpf.h>
     18#include <bpf/bpf.h>
     19#include <bpf/libbpf.h>
     20
     21#include "cgroup_helpers.h"
     22#include "testing_helpers.h"
     23
     24#define CHECK(condition, tag, format...) ({		\
     25	int __ret = !!(condition);			\
     26	if (__ret) {					\
     27		printf("%s:FAIL:%s ", __func__, tag);	\
     28		printf(format);				\
     29	} else {					\
     30		printf("%s:PASS:%s\n", __func__, tag);	\
     31	}						\
     32	__ret;						\
     33})
     34
     35static int bpf_find_map(const char *test, struct bpf_object *obj,
     36			const char *name)
     37{
     38	struct bpf_map *map;
     39
     40	map = bpf_object__find_map_by_name(obj, name);
     41	if (!map)
     42		return -1;
     43	return bpf_map__fd(map);
     44}
     45
     46#define TEST_CGROUP "/test-bpf-get-cgroup-id/"
     47
     48int main(int argc, char **argv)
     49{
     50	const char *probe_name = "syscalls/sys_enter_nanosleep";
     51	const char *file = "get_cgroup_id_kern.o";
     52	int err, bytes, efd, prog_fd, pmu_fd;
     53	int cgroup_fd, cgidmap_fd, pidmap_fd;
     54	struct perf_event_attr attr = {};
     55	struct bpf_object *obj;
     56	__u64 kcgid = 0, ucgid;
     57	__u32 key = 0, pid;
     58	int exit_code = 1;
     59	char buf[256];
     60	const struct timespec req = {
     61		.tv_sec = 1,
     62		.tv_nsec = 0,
     63	};
     64
     65	cgroup_fd = cgroup_setup_and_join(TEST_CGROUP);
     66	if (CHECK(cgroup_fd < 0, "cgroup_setup_and_join", "err %d errno %d\n", cgroup_fd, errno))
     67		return 1;
     68
     69	/* Use libbpf 1.0 API mode */
     70	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
     71
     72	err = bpf_prog_test_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
     73	if (CHECK(err, "bpf_prog_test_load", "err %d errno %d\n", err, errno))
     74		goto cleanup_cgroup_env;
     75
     76	cgidmap_fd = bpf_find_map(__func__, obj, "cg_ids");
     77	if (CHECK(cgidmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
     78		  cgidmap_fd, errno))
     79		goto close_prog;
     80
     81	pidmap_fd = bpf_find_map(__func__, obj, "pidmap");
     82	if (CHECK(pidmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
     83		  pidmap_fd, errno))
     84		goto close_prog;
     85
     86	pid = getpid();
     87	bpf_map_update_elem(pidmap_fd, &key, &pid, 0);
     88
     89	snprintf(buf, sizeof(buf),
     90		 "/sys/kernel/debug/tracing/events/%s/id", probe_name);
     91	efd = open(buf, O_RDONLY, 0);
     92	if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
     93		goto close_prog;
     94	bytes = read(efd, buf, sizeof(buf));
     95	close(efd);
     96	if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read",
     97		  "bytes %d errno %d\n", bytes, errno))
     98		goto close_prog;
     99
    100	attr.config = strtol(buf, NULL, 0);
    101	attr.type = PERF_TYPE_TRACEPOINT;
    102	attr.sample_type = PERF_SAMPLE_RAW;
    103	attr.sample_period = 1;
    104	attr.wakeup_events = 1;
    105
    106	/* attach to this pid so the all bpf invocations will be in the
    107	 * cgroup associated with this pid.
    108	 */
    109	pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
    110	if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
    111		  errno))
    112		goto close_prog;
    113
    114	err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
    115	if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err,
    116		  errno))
    117		goto close_pmu;
    118
    119	err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
    120	if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err,
    121		  errno))
    122		goto close_pmu;
    123
    124	/* trigger some syscalls */
    125	syscall(__NR_nanosleep, &req, NULL);
    126
    127	err = bpf_map_lookup_elem(cgidmap_fd, &key, &kcgid);
    128	if (CHECK(err, "bpf_map_lookup_elem", "err %d errno %d\n", err, errno))
    129		goto close_pmu;
    130
    131	ucgid = get_cgroup_id(TEST_CGROUP);
    132	if (CHECK(kcgid != ucgid, "compare_cgroup_id",
    133		  "kern cgid %llx user cgid %llx", kcgid, ucgid))
    134		goto close_pmu;
    135
    136	exit_code = 0;
    137	printf("%s:PASS\n", argv[0]);
    138
    139close_pmu:
    140	close(pmu_fd);
    141close_prog:
    142	bpf_object__close(obj);
    143cleanup_cgroup_env:
    144	cleanup_cgroup_environment();
    145	return exit_code;
    146}