root/tools/testing/selftests/bpf/get_cgroup_id_user.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bpf_find_map
  2. main

   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 "bpf_rlimit.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 
  35 static 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 
  48 int 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 
  61         err = setup_cgroup_environment();
  62         if (CHECK(err, "setup_cgroup_environment", "err %d errno %d\n", err,
  63                   errno))
  64                 return 1;
  65 
  66         cgroup_fd = create_and_get_cgroup(TEST_CGROUP);
  67         if (CHECK(cgroup_fd < 0, "create_and_get_cgroup", "err %d errno %d\n",
  68                   cgroup_fd, errno))
  69                 goto cleanup_cgroup_env;
  70 
  71         err = join_cgroup(TEST_CGROUP);
  72         if (CHECK(err, "join_cgroup", "err %d errno %d\n", err, errno))
  73                 goto cleanup_cgroup_env;
  74 
  75         err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
  76         if (CHECK(err, "bpf_prog_load", "err %d errno %d\n", err, errno))
  77                 goto cleanup_cgroup_env;
  78 
  79         cgidmap_fd = bpf_find_map(__func__, obj, "cg_ids");
  80         if (CHECK(cgidmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
  81                   cgidmap_fd, errno))
  82                 goto close_prog;
  83 
  84         pidmap_fd = bpf_find_map(__func__, obj, "pidmap");
  85         if (CHECK(pidmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
  86                   pidmap_fd, errno))
  87                 goto close_prog;
  88 
  89         pid = getpid();
  90         bpf_map_update_elem(pidmap_fd, &key, &pid, 0);
  91 
  92         snprintf(buf, sizeof(buf),
  93                  "/sys/kernel/debug/tracing/events/%s/id", probe_name);
  94         efd = open(buf, O_RDONLY, 0);
  95         if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
  96                 goto close_prog;
  97         bytes = read(efd, buf, sizeof(buf));
  98         close(efd);
  99         if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read",
 100                   "bytes %d errno %d\n", bytes, errno))
 101                 goto close_prog;
 102 
 103         attr.config = strtol(buf, NULL, 0);
 104         attr.type = PERF_TYPE_TRACEPOINT;
 105         attr.sample_type = PERF_SAMPLE_RAW;
 106         attr.sample_period = 1;
 107         attr.wakeup_events = 1;
 108 
 109         /* attach to this pid so the all bpf invocations will be in the
 110          * cgroup associated with this pid.
 111          */
 112         pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
 113         if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
 114                   errno))
 115                 goto close_prog;
 116 
 117         err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
 118         if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err,
 119                   errno))
 120                 goto close_pmu;
 121 
 122         err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
 123         if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err,
 124                   errno))
 125                 goto close_pmu;
 126 
 127         /* trigger some syscalls */
 128         sleep(1);
 129 
 130         err = bpf_map_lookup_elem(cgidmap_fd, &key, &kcgid);
 131         if (CHECK(err, "bpf_map_lookup_elem", "err %d errno %d\n", err, errno))
 132                 goto close_pmu;
 133 
 134         ucgid = get_cgroup_id(TEST_CGROUP);
 135         if (CHECK(kcgid != ucgid, "compare_cgroup_id",
 136                   "kern cgid %llx user cgid %llx", kcgid, ucgid))
 137                 goto close_pmu;
 138 
 139         exit_code = 0;
 140         printf("%s:PASS\n", argv[0]);
 141 
 142 close_pmu:
 143         close(pmu_fd);
 144 close_prog:
 145         bpf_object__close(obj);
 146 cleanup_cgroup_env:
 147         cleanup_cgroup_environment();
 148         return exit_code;
 149 }

/* [<][>][^][v][top][bottom][index][help] */