1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018 Facebook
11 #include <linux/perf_event.h>
12 #include <sys/ioctl.h>
14 #include <sys/types.h>
17 #include <linux/bpf.h>
19 #include <bpf/libbpf.h>
21 #include "cgroup_helpers.h"
22 #include "bpf_rlimit.h"
24 #define CHECK(condition, tag, format...) ({ \
25 int __ret = !!(condition); \
27 printf("%s:FAIL:%s ", __func__, tag); \
30 printf("%s:PASS:%s\n", __func__, tag); \
35 static int bpf_find_map(const char *test
, struct bpf_object
*obj
,
40 map
= bpf_object__find_map_by_name(obj
, name
);
43 return bpf_map__fd(map
);
46 #define TEST_CGROUP "/test-bpf-get-cgroup-id/"
48 int main(int argc
, char **argv
)
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
;
61 err
= setup_cgroup_environment();
62 if (CHECK(err
, "setup_cgroup_environment", "err %d errno %d\n", err
,
66 cgroup_fd
= create_and_get_cgroup(TEST_CGROUP
);
67 if (CHECK(cgroup_fd
< 0, "create_and_get_cgroup", "err %d errno %d\n",
69 goto cleanup_cgroup_env
;
71 err
= join_cgroup(TEST_CGROUP
);
72 if (CHECK(err
, "join_cgroup", "err %d errno %d\n", err
, errno
))
73 goto cleanup_cgroup_env
;
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
;
79 cgidmap_fd
= bpf_find_map(__func__
, obj
, "cg_ids");
80 if (CHECK(cgidmap_fd
< 0, "bpf_find_map", "err %d errno %d\n",
84 pidmap_fd
= bpf_find_map(__func__
, obj
, "pidmap");
85 if (CHECK(pidmap_fd
< 0, "bpf_find_map", "err %d errno %d\n",
90 bpf_map_update_elem(pidmap_fd
, &key
, &pid
, 0);
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
))
97 bytes
= read(efd
, buf
, sizeof(buf
));
99 if (CHECK(bytes
<= 0 || bytes
>= sizeof(buf
), "read",
100 "bytes %d errno %d\n", bytes
, errno
))
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;
109 /* attach to this pid so the all bpf invocations will be in the
110 * cgroup associated with this pid.
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
,
117 err
= ioctl(pmu_fd
, PERF_EVENT_IOC_ENABLE
, 0);
118 if (CHECK(err
, "perf_event_ioc_enable", "err %d errno %d\n", err
,
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
,
127 /* trigger some syscalls */
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
))
134 ucgid
= get_cgroup_id(TEST_CGROUP
);
135 if (CHECK(kcgid
!= ucgid
, "compare_cgroup_id",
136 "kern cgid %llx user cgid %llx", kcgid
, ucgid
))
140 printf("%s:PASS\n", argv
[0]);
145 bpf_object__close(obj
);
147 cleanup_cgroup_environment();