summaryrefslogtreecommitdiff
path: root/tools/testing
diff options
context:
space:
mode:
authorWoojin Ji <random6.xyz@gmail.com>2026-10-18 13:21:42 +0900
committerAlexei Starovoitov <ast@kernel.org>2026-10-18 15:28:51 +0000
commit38dbc3047a2fa706f6b4485679eb5eb62ff55b87 (patch)
tree18fa2bafea471c3a1f294417a138a68f286e34e9 /tools/testing
parent1c1dda9ba9f3af9cd511a197dcc86de2465d8fe5 (diff)
selftests/bpf: Test out-of-range index bits in bpf_get_func_arg()
The inlined expansion of bpf_get_func_arg() bounds-checks only the low 32 bits of the index, so a helper prototype that keeps the upper bits of the index is needed to reach it. Add check_wide_index() and call it from the fexit and tp_btf tests. It drives the helper with indices that have upper bits set and with indices whose low 32 bits are out of range, and it checks that the destination is left untouched when the helper reports -EINVAL. Without the previous patch the wide index is shifted as 64-bit and the load uses an address far outside the context. Signed-off-by: Woojin Ji <random6.xyz@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://patch.msgid.link/20261018-get-func-arg-v2-2-048848b3eddf@gmail.com
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/selftests/bpf/progs/get_func_args_test.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c
index 1bf47f64d096..9b0beb58d88d 100644
--- a/tools/testing/selftests/bpf/progs/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c
@@ -6,6 +6,40 @@
char _license[] SEC("license") = "GPL";
+/* Keep the upper index bits: the inlined expansion must truncate them. */
+static long (*bpf_get_func_arg_wide)(void *ctx, __u64 n, __u64 *value) =
+ (void *)BPF_FUNC_get_func_arg;
+
+/* Both traced functions are called with arguments 2 and 3. */
+static __always_inline int check_wide_index(void *ctx)
+{
+ __u64 a = 0, z = 0xdeadbeefdeadbeefULL;
+ __s64 err;
+ int ok = 1;
+
+ /* The index is truncated to u32, so these select arguments 0 and 1. */
+ err = bpf_get_func_arg_wide(ctx, 1ULL << 32, &a);
+ ok &= err == 0 && ((int)a == 2);
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 32) | 1, &a);
+ ok &= err == 0 && a == 3;
+ err = bpf_get_func_arg_wide(ctx, 1ULL << 59, &a);
+ ok &= err == 0 && ((int)a == 2);
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 59) | 1, &a);
+ ok &= err == 0 && a == 3;
+
+ /* Out of range: -EINVAL and no store into the destination. */
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 32) | 2, &z);
+ ok &= err == -EINVAL && z == 0xdeadbeefdeadbeefULL;
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 32) | 0xffffffffULL, &z);
+ ok &= err == -EINVAL && z == 0xdeadbeefdeadbeefULL;
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 59) | 2, &z);
+ ok &= err == -EINVAL && z == 0xdeadbeefdeadbeefULL;
+ err = bpf_get_func_arg_wide(ctx, (1ULL << 59) | 0xffffffffULL, &z);
+ ok &= err == -EINVAL && z == 0xdeadbeefdeadbeefULL;
+
+ return ok;
+}
+
__u64 test1_result = 0;
SEC("fentry/bpf_fentry_test1")
int BPF_PROG(test1)
@@ -63,6 +97,7 @@ int BPF_PROG(test2)
/* return value */
err = bpf_get_func_ret(ctx, &ret);
test2_result &= err == 0 && ret == 5;
+ test2_result &= check_wide_index(ctx);
return 0;
}
@@ -162,6 +197,7 @@ int BPF_PROG(tp_test2)
/* not valid argument */
err = bpf_get_func_arg(ctx, 2, &z);
test6_result &= err == -EINVAL;
+ test6_result &= check_wide_index(ctx);
return 0;
}