1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 4 #include <vmlinux.h> 5 #include <bpf/bpf_tracing.h> 6 #include <bpf/bpf_helpers.h> 7 #include <bpf/bpf_core_read.h> 8 #include "bpf_experimental.h" 9 #include "bpf_misc.h" 10 11 char _license[] SEC("license") = "GPL"; 12 13 char value[16]; 14 15 static __always_inline void read_xattr(struct cgroup *cgroup) 16 { 17 struct bpf_dynptr value_ptr; 18 19 bpf_dynptr_from_mem(value, sizeof(value), 0, &value_ptr); 20 bpf_cgroup_read_xattr(cgroup, "user.bpf_test", 21 &value_ptr); 22 } 23 24 SEC("lsm.s/socket_connect") 25 __success 26 int BPF_PROG(trusted_cgroup_ptr_sleepable) 27 { 28 u64 cgrp_id = bpf_get_current_cgroup_id(); 29 struct cgroup *cgrp; 30 31 cgrp = bpf_cgroup_from_id(cgrp_id); 32 if (!cgrp) 33 return 0; 34 35 read_xattr(cgrp); 36 bpf_cgroup_release(cgrp); 37 return 0; 38 } 39 40 SEC("lsm/socket_connect") 41 __success 42 int BPF_PROG(trusted_cgroup_ptr_non_sleepable) 43 { 44 u64 cgrp_id = bpf_get_current_cgroup_id(); 45 struct cgroup *cgrp; 46 47 cgrp = bpf_cgroup_from_id(cgrp_id); 48 if (!cgrp) 49 return 0; 50 51 read_xattr(cgrp); 52 bpf_cgroup_release(cgrp); 53 return 0; 54 } 55 56 SEC("lsm/socket_connect") 57 __success 58 int BPF_PROG(use_css_iter_non_sleepable) 59 { 60 u64 cgrp_id = bpf_get_current_cgroup_id(); 61 struct cgroup_subsys_state *css; 62 struct cgroup *cgrp; 63 64 cgrp = bpf_cgroup_from_id(cgrp_id); 65 if (!cgrp) 66 return 0; 67 68 bpf_for_each(css, css, &cgrp->self, BPF_CGROUP_ITER_ANCESTORS_UP) 69 read_xattr(css->cgroup); 70 71 bpf_cgroup_release(cgrp); 72 return 0; 73 } 74 75 SEC("lsm.s/socket_connect") 76 __failure __msg("expected an RCU CS") 77 int BPF_PROG(use_css_iter_sleepable_missing_rcu_lock) 78 { 79 u64 cgrp_id = bpf_get_current_cgroup_id(); 80 struct cgroup_subsys_state *css; 81 struct cgroup *cgrp; 82 83 cgrp = bpf_cgroup_from_id(cgrp_id); 84 if (!cgrp) 85 return 0; 86 87 bpf_for_each(css, css, &cgrp->self, BPF_CGROUP_ITER_ANCESTORS_UP) 88 read_xattr(css->cgroup); 89 90 bpf_cgroup_release(cgrp); 91 return 0; 92 } 93 94 SEC("lsm.s/socket_connect") 95 __success 96 int BPF_PROG(use_css_iter_sleepable_with_rcu_lock) 97 { 98 u64 cgrp_id = bpf_get_current_cgroup_id(); 99 struct cgroup_subsys_state *css; 100 struct cgroup *cgrp; 101 102 bpf_rcu_read_lock(); 103 cgrp = bpf_cgroup_from_id(cgrp_id); 104 if (!cgrp) 105 goto out; 106 107 bpf_for_each(css, css, &cgrp->self, BPF_CGROUP_ITER_ANCESTORS_UP) 108 read_xattr(css->cgroup); 109 110 bpf_cgroup_release(cgrp); 111 out: 112 bpf_rcu_read_unlock(); 113 return 0; 114 } 115 116 SEC("lsm/socket_connect") 117 __success 118 int BPF_PROG(use_bpf_cgroup_ancestor) 119 { 120 u64 cgrp_id = bpf_get_current_cgroup_id(); 121 struct cgroup *cgrp, *ancestor; 122 123 cgrp = bpf_cgroup_from_id(cgrp_id); 124 if (!cgrp) 125 return 0; 126 127 ancestor = bpf_cgroup_ancestor(cgrp, 1); 128 if (!ancestor) 129 goto out; 130 131 read_xattr(cgrp); 132 bpf_cgroup_release(ancestor); 133 out: 134 bpf_cgroup_release(cgrp); 135 return 0; 136 } 137 138 SEC("cgroup/sendmsg4") 139 __success 140 int BPF_PROG(cgroup_skb) 141 { 142 u64 cgrp_id = bpf_get_current_cgroup_id(); 143 struct cgroup *cgrp, *ancestor; 144 145 cgrp = bpf_cgroup_from_id(cgrp_id); 146 if (!cgrp) 147 return 0; 148 149 ancestor = bpf_cgroup_ancestor(cgrp, 1); 150 if (!ancestor) 151 goto out; 152 153 read_xattr(cgrp); 154 bpf_cgroup_release(ancestor); 155 out: 156 bpf_cgroup_release(cgrp); 157 return 0; 158 } 159