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

selftests/bpf: add another struct_ops callback use case test

Add a test which tests the case that was just fixed. Kernel has full
type information about callback, but user explicitly nulls out the
reference to declaratively set BPF program reference.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20240507001335.1445325-4-andrii@kernel.org
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

authored by

Andrii Nakryiko and committed by
Martin KaFai Lau
9d66d60e e18e2e70

+49
+27
tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
··· 4 4 #include <time.h> 5 5 6 6 #include "struct_ops_module.skel.h" 7 + #include "struct_ops_nulled_out_cb.skel.h" 7 8 8 9 static void check_map_info(struct bpf_map_info *info) 9 10 { ··· 175 174 struct_ops_module__destroy(skel); 176 175 } 177 176 177 + /* validate that it's ok to "turn off" callback that kernel supports */ 178 + static void test_struct_ops_nulled_out_cb(void) 179 + { 180 + struct struct_ops_nulled_out_cb *skel; 181 + int err; 182 + 183 + skel = struct_ops_nulled_out_cb__open(); 184 + if (!ASSERT_OK_PTR(skel, "skel_open")) 185 + return; 186 + 187 + /* kernel knows about test_1, but we still null it out */ 188 + skel->struct_ops.ops->test_1 = NULL; 189 + 190 + err = struct_ops_nulled_out_cb__load(skel); 191 + if (!ASSERT_OK(err, "skel_load")) 192 + goto cleanup; 193 + 194 + ASSERT_FALSE(bpf_program__autoload(skel->progs.test_1_turn_off), "prog_autoload"); 195 + ASSERT_LT(bpf_program__fd(skel->progs.test_1_turn_off), 0, "prog_fd"); 196 + 197 + cleanup: 198 + struct_ops_nulled_out_cb__destroy(skel); 199 + } 200 + 178 201 void serial_test_struct_ops_module(void) 179 202 { 180 203 if (test__start_subtest("test_struct_ops_load")) ··· 207 182 test_struct_ops_not_zeroed(); 208 183 if (test__start_subtest("test_struct_ops_incompatible")) 209 184 test_struct_ops_incompatible(); 185 + if (test__start_subtest("test_struct_ops_null_out_cb")) 186 + test_struct_ops_nulled_out_cb(); 210 187 } 211 188
+22
tools/testing/selftests/bpf/progs/struct_ops_nulled_out_cb.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <vmlinux.h> 4 + #include <bpf/bpf_tracing.h> 5 + #include "../bpf_testmod/bpf_testmod.h" 6 + 7 + char _license[] SEC("license") = "GPL"; 8 + 9 + int rand; 10 + int arr[1]; 11 + 12 + SEC("struct_ops/test_1") 13 + int BPF_PROG(test_1_turn_off) 14 + { 15 + return arr[rand]; /* potentially way out of range access */ 16 + } 17 + 18 + SEC(".struct_ops.link") 19 + struct bpf_testmod_ops ops = { 20 + .test_1 = (void *)test_1_turn_off, 21 + }; 22 +