-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/bpf: Test returning referenced kptr from struct_ops programs
Test struct_ops programs returning referenced kptr. When the return type of a struct_ops operator is pointer to struct, the verifier should only allow programs that return a scalar NULL or a non-local kptr with the correct type in its unmodified form. Signed-off-by: Amery Hung <amery.hung@bytedance.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Acked-by: Martin KaFai Lau <martin.lau@kernel.org> Link: https://lore.kernel.org/r/20250217190640.1748177-6-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
Amery Hung
authored and
Alexei Starovoitov
committed
Feb 18, 2025
1 parent
8d9f547
commit af17bad
Showing
8 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
tools/testing/selftests/bpf/prog_tests/test_struct_ops_kptr_return.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <test_progs.h> | ||
|
||
#include "struct_ops_kptr_return.skel.h" | ||
#include "struct_ops_kptr_return_fail__wrong_type.skel.h" | ||
#include "struct_ops_kptr_return_fail__invalid_scalar.skel.h" | ||
#include "struct_ops_kptr_return_fail__nonzero_offset.skel.h" | ||
#include "struct_ops_kptr_return_fail__local_kptr.skel.h" | ||
|
||
void test_struct_ops_kptr_return(void) | ||
{ | ||
RUN_TESTS(struct_ops_kptr_return); | ||
RUN_TESTS(struct_ops_kptr_return_fail__wrong_type); | ||
RUN_TESTS(struct_ops_kptr_return_fail__invalid_scalar); | ||
RUN_TESTS(struct_ops_kptr_return_fail__nonzero_offset); | ||
RUN_TESTS(struct_ops_kptr_return_fail__local_kptr); | ||
} |
30 changes: 30 additions & 0 deletions
30
tools/testing/selftests/bpf/progs/struct_ops_kptr_return.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../test_kmods/bpf_testmod.h" | ||
#include "bpf_misc.h" | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
void bpf_task_release(struct task_struct *p) __ksym; | ||
|
||
/* This test struct_ops BPF programs returning referenced kptr. The verifier should | ||
* allow a referenced kptr or a NULL pointer to be returned. A referenced kptr to task | ||
* here is acquried automatically as the task argument is tagged with "__ref". | ||
*/ | ||
SEC("struct_ops/test_return_ref_kptr") | ||
struct task_struct *BPF_PROG(kptr_return, int dummy, | ||
struct task_struct *task, struct cgroup *cgrp) | ||
{ | ||
if (dummy % 2) { | ||
bpf_task_release(task); | ||
return NULL; | ||
} | ||
return task; | ||
} | ||
|
||
SEC(".struct_ops.link") | ||
struct bpf_testmod_ops testmod_kptr_return = { | ||
.test_return_ref_kptr = (void *)kptr_return, | ||
}; | ||
|
||
|
26 changes: 26 additions & 0 deletions
26
tools/testing/selftests/bpf/progs/struct_ops_kptr_return_fail__invalid_scalar.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../test_kmods/bpf_testmod.h" | ||
#include "bpf_misc.h" | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; | ||
void bpf_task_release(struct task_struct *p) __ksym; | ||
|
||
/* This test struct_ops BPF programs returning referenced kptr. The verifier should | ||
* reject programs returning a non-zero scalar value. | ||
*/ | ||
SEC("struct_ops/test_return_ref_kptr") | ||
__failure __msg("At program exit the register R0 has smin=1 smax=1 should have been in [0, 0]") | ||
struct task_struct *BPF_PROG(kptr_return_fail__invalid_scalar, int dummy, | ||
struct task_struct *task, struct cgroup *cgrp) | ||
{ | ||
bpf_task_release(task); | ||
return (struct task_struct *)1; | ||
} | ||
|
||
SEC(".struct_ops.link") | ||
struct bpf_testmod_ops testmod_kptr_return = { | ||
.test_return_ref_kptr = (void *)kptr_return_fail__invalid_scalar, | ||
}; |
34 changes: 34 additions & 0 deletions
34
tools/testing/selftests/bpf/progs/struct_ops_kptr_return_fail__local_kptr.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../test_kmods/bpf_testmod.h" | ||
#include "bpf_experimental.h" | ||
#include "bpf_misc.h" | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; | ||
void bpf_task_release(struct task_struct *p) __ksym; | ||
|
||
/* This test struct_ops BPF programs returning referenced kptr. The verifier should | ||
* reject programs returning a local kptr. | ||
*/ | ||
SEC("struct_ops/test_return_ref_kptr") | ||
__failure __msg("At program exit the register R0 is not a known value (ptr_or_null_)") | ||
struct task_struct *BPF_PROG(kptr_return_fail__local_kptr, int dummy, | ||
struct task_struct *task, struct cgroup *cgrp) | ||
{ | ||
struct task_struct *t; | ||
|
||
bpf_task_release(task); | ||
|
||
t = bpf_obj_new(typeof(*task)); | ||
if (!t) | ||
return NULL; | ||
|
||
return t; | ||
} | ||
|
||
SEC(".struct_ops.link") | ||
struct bpf_testmod_ops testmod_kptr_return = { | ||
.test_return_ref_kptr = (void *)kptr_return_fail__local_kptr, | ||
}; |
25 changes: 25 additions & 0 deletions
25
tools/testing/selftests/bpf/progs/struct_ops_kptr_return_fail__nonzero_offset.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../test_kmods/bpf_testmod.h" | ||
#include "bpf_misc.h" | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; | ||
void bpf_task_release(struct task_struct *p) __ksym; | ||
|
||
/* This test struct_ops BPF programs returning referenced kptr. The verifier should | ||
* reject programs returning a modified referenced kptr. | ||
*/ | ||
SEC("struct_ops/test_return_ref_kptr") | ||
__failure __msg("dereference of modified trusted_ptr_ ptr R0 off={{[0-9]+}} disallowed") | ||
struct task_struct *BPF_PROG(kptr_return_fail__nonzero_offset, int dummy, | ||
struct task_struct *task, struct cgroup *cgrp) | ||
{ | ||
return (struct task_struct *)&task->jobctl; | ||
} | ||
|
||
SEC(".struct_ops.link") | ||
struct bpf_testmod_ops testmod_kptr_return = { | ||
.test_return_ref_kptr = (void *)kptr_return_fail__nonzero_offset, | ||
}; |
30 changes: 30 additions & 0 deletions
30
tools/testing/selftests/bpf/progs/struct_ops_kptr_return_fail__wrong_type.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../test_kmods/bpf_testmod.h" | ||
#include "bpf_misc.h" | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; | ||
void bpf_task_release(struct task_struct *p) __ksym; | ||
|
||
/* This test struct_ops BPF programs returning referenced kptr. The verifier should | ||
* reject programs returning a referenced kptr of the wrong type. | ||
*/ | ||
SEC("struct_ops/test_return_ref_kptr") | ||
__failure __msg("At program exit the register R0 is not a known value (ptr_or_null_)") | ||
struct task_struct *BPF_PROG(kptr_return_fail__wrong_type, int dummy, | ||
struct task_struct *task, struct cgroup *cgrp) | ||
{ | ||
struct task_struct *ret; | ||
|
||
ret = (struct task_struct *)bpf_cgroup_acquire(cgrp); | ||
bpf_task_release(task); | ||
|
||
return ret; | ||
} | ||
|
||
SEC(".struct_ops.link") | ||
struct bpf_testmod_ops testmod_kptr_return = { | ||
.test_return_ref_kptr = (void *)kptr_return_fail__wrong_type, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters