1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3
4 #include "bpf_iter.h"
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7 #include "bpf_misc.h"
8
9 char _license[] SEC("license") = "GPL";
10
11 struct {
12 __uint(type, BPF_MAP_TYPE_CGRP_STORAGE);
13 __uint(map_flags, BPF_F_NO_PREALLOC);
14 __type(key, int);
15 __type(value, long);
16 } map_a SEC(".maps");
17
18 __u32 target_pid;
19 __u64 cgroup_id;
20
21 void bpf_rcu_read_lock(void) __ksym;
22 void bpf_rcu_read_unlock(void) __ksym;
23
24 SEC("?iter.s/cgroup")
cgroup_iter(struct bpf_iter__cgroup * ctx)25 int cgroup_iter(struct bpf_iter__cgroup *ctx)
26 {
27 struct cgroup *cgrp = ctx->cgroup;
28 long *ptr;
29
30 if (cgrp == NULL)
31 return 0;
32
33 ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0,
34 BPF_LOCAL_STORAGE_GET_F_CREATE);
35 if (ptr)
36 cgroup_id = cgrp->kn->id;
37 return 0;
38 }
39
40 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
no_rcu_lock(void * ctx)41 int no_rcu_lock(void *ctx)
42 {
43 struct task_struct *task;
44 struct cgroup *cgrp;
45 long *ptr;
46
47 task = bpf_get_current_task_btf();
48 if (task->pid != target_pid)
49 return 0;
50
51 /* task->cgroups is untrusted in sleepable prog outside of RCU CS */
52 cgrp = task->cgroups->dfl_cgrp;
53 ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0,
54 BPF_LOCAL_STORAGE_GET_F_CREATE);
55 if (ptr)
56 cgroup_id = cgrp->kn->id;
57 return 0;
58 }
59
60 SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
yes_rcu_lock(void * ctx)61 int yes_rcu_lock(void *ctx)
62 {
63 struct task_struct *task;
64 struct cgroup *cgrp;
65 long *ptr;
66
67 task = bpf_get_current_task_btf();
68 if (task->pid != target_pid)
69 return 0;
70
71 bpf_rcu_read_lock();
72 cgrp = task->cgroups->dfl_cgrp;
73 /* cgrp is trusted under RCU CS */
74 ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0, BPF_LOCAL_STORAGE_GET_F_CREATE);
75 if (ptr)
76 cgroup_id = cgrp->kn->id;
77 bpf_rcu_read_unlock();
78 return 0;
79 }
80