Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: add tests confirming type logic in kernel for __arg_ctx

Add a bunch of global subprogs across variety of program types to
validate expected kernel type enforcement logic for __arg_ctx arguments.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20240118033143.3384355-5-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
989410cd 0ba97151

+161 -3
+161 -3
tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
··· 3 3 4 4 #include <vmlinux.h> 5 5 #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 6 7 #include "bpf_misc.h" 7 8 #include "xdp_metadata.h" 8 9 #include "bpf_kfuncs.h" ··· 139 138 return bpf_get_stack(ctx, stack, sizeof(stack), 0); 140 139 } 141 140 141 + __weak int raw_tp_canonical(struct bpf_raw_tracepoint_args *ctx __arg_ctx) 142 + { 143 + return 0; 144 + } 145 + 146 + __weak int raw_tp_u64_array(u64 *ctx __arg_ctx) 147 + { 148 + return 0; 149 + } 150 + 142 151 SEC("?raw_tp") 143 152 __success __log_level(2) 144 153 int arg_tag_ctx_raw_tp(void *ctx) 145 154 { 146 - return subprog_ctx_tag(ctx); 155 + return subprog_ctx_tag(ctx) + raw_tp_canonical(ctx) + raw_tp_u64_array(ctx); 156 + } 157 + 158 + SEC("?raw_tp.w") 159 + __success __log_level(2) 160 + int arg_tag_ctx_raw_tp_writable(void *ctx) 161 + { 162 + return subprog_ctx_tag(ctx) + raw_tp_canonical(ctx) + raw_tp_u64_array(ctx); 163 + } 164 + 165 + SEC("?tp_btf/sys_enter") 166 + __success __log_level(2) 167 + int arg_tag_ctx_raw_tp_btf(void *ctx) 168 + { 169 + return subprog_ctx_tag(ctx) + raw_tp_canonical(ctx) + raw_tp_u64_array(ctx); 170 + } 171 + 172 + struct whatever { }; 173 + 174 + __weak int tp_whatever(struct whatever *ctx __arg_ctx) 175 + { 176 + return 0; 147 177 } 148 178 149 179 SEC("?tp") 150 180 __success __log_level(2) 151 181 int arg_tag_ctx_tp(void *ctx) 152 182 { 153 - return subprog_ctx_tag(ctx); 183 + return subprog_ctx_tag(ctx) + tp_whatever(ctx); 184 + } 185 + 186 + __weak int kprobe_subprog_pt_regs(struct pt_regs *ctx __arg_ctx) 187 + { 188 + return 0; 189 + } 190 + 191 + __weak int kprobe_subprog_typedef(bpf_user_pt_regs_t *ctx __arg_ctx) 192 + { 193 + return 0; 154 194 } 155 195 156 196 SEC("?kprobe") 157 197 __success __log_level(2) 158 198 int arg_tag_ctx_kprobe(void *ctx) 159 199 { 160 - return subprog_ctx_tag(ctx); 200 + return subprog_ctx_tag(ctx) + 201 + kprobe_subprog_pt_regs(ctx) + 202 + kprobe_subprog_typedef(ctx); 203 + } 204 + 205 + __weak int perf_subprog_regs( 206 + #if defined(bpf_target_riscv) 207 + struct user_regs_struct *ctx __arg_ctx 208 + #elif defined(bpf_target_s390) 209 + /* user_pt_regs typedef is anonymous struct, so only `void *` works */ 210 + void *ctx __arg_ctx 211 + #elif defined(bpf_target_loongarch) || defined(bpf_target_arm64) || defined(bpf_target_powerpc) 212 + struct user_pt_regs *ctx __arg_ctx 213 + #else 214 + struct pt_regs *ctx __arg_ctx 215 + #endif 216 + ) 217 + { 218 + return 0; 219 + } 220 + 221 + __weak int perf_subprog_typedef(bpf_user_pt_regs_t *ctx __arg_ctx) 222 + { 223 + return 0; 224 + } 225 + 226 + __weak int perf_subprog_canonical(struct bpf_perf_event_data *ctx __arg_ctx) 227 + { 228 + return 0; 229 + } 230 + 231 + SEC("?perf_event") 232 + __success __log_level(2) 233 + int arg_tag_ctx_perf(void *ctx) 234 + { 235 + return subprog_ctx_tag(ctx) + 236 + perf_subprog_regs(ctx) + 237 + perf_subprog_typedef(ctx) + 238 + perf_subprog_canonical(ctx); 239 + } 240 + 241 + __weak int iter_subprog_void(void *ctx __arg_ctx) 242 + { 243 + return 0; 244 + } 245 + 246 + __weak int iter_subprog_typed(struct bpf_iter__task *ctx __arg_ctx) 247 + { 248 + return 0; 249 + } 250 + 251 + SEC("?iter/task") 252 + __success __log_level(2) 253 + int arg_tag_ctx_iter_task(struct bpf_iter__task *ctx) 254 + { 255 + return (iter_subprog_void(ctx) + iter_subprog_typed(ctx)) & 1; 256 + } 257 + 258 + __weak int tracing_subprog_void(void *ctx __arg_ctx) 259 + { 260 + return 0; 261 + } 262 + 263 + __weak int tracing_subprog_u64(u64 *ctx __arg_ctx) 264 + { 265 + return 0; 266 + } 267 + 268 + int acc; 269 + 270 + SEC("?fentry/" SYS_PREFIX "sys_nanosleep") 271 + __success __log_level(2) 272 + int BPF_PROG(arg_tag_ctx_fentry) 273 + { 274 + acc += tracing_subprog_void(ctx) + tracing_subprog_u64(ctx); 275 + return 0; 276 + } 277 + 278 + SEC("?fexit/" SYS_PREFIX "sys_nanosleep") 279 + __success __log_level(2) 280 + int BPF_PROG(arg_tag_ctx_fexit) 281 + { 282 + acc += tracing_subprog_void(ctx) + tracing_subprog_u64(ctx); 283 + return 0; 284 + } 285 + 286 + SEC("?fmod_ret/" SYS_PREFIX "sys_nanosleep") 287 + __success __log_level(2) 288 + int BPF_PROG(arg_tag_ctx_fmod_ret) 289 + { 290 + return tracing_subprog_void(ctx) + tracing_subprog_u64(ctx); 291 + } 292 + 293 + SEC("?lsm/bpf") 294 + __success __log_level(2) 295 + int BPF_PROG(arg_tag_ctx_lsm) 296 + { 297 + return tracing_subprog_void(ctx) + tracing_subprog_u64(ctx); 298 + } 299 + 300 + SEC("?struct_ops/test_1") 301 + __success __log_level(2) 302 + int BPF_PROG(arg_tag_ctx_struct_ops) 303 + { 304 + return tracing_subprog_void(ctx) + tracing_subprog_u64(ctx); 305 + } 306 + 307 + SEC(".struct_ops") 308 + struct bpf_dummy_ops dummy_1 = { 309 + .test_1 = (void *)arg_tag_ctx_struct_ops, 310 + }; 311 + 312 + SEC("?syscall") 313 + __success __log_level(2) 314 + int arg_tag_ctx_syscall(void *ctx) 315 + { 316 + return tracing_subprog_void(ctx) + tracing_subprog_u64(ctx) + tp_whatever(ctx); 161 317 } 162 318 163 319 __weak int subprog_dynptr(struct bpf_dynptr *dptr)