This patch adds test cases for struct file related CRIB kfuncs. The test case for bpf_fget_task() is written based on files_test_process(), so there should only be 3 opened files, corresponding to file descriptors 0, 1, 2. bpf_get_file_ops_type() currently only returns FILE_OPS_UNKNOWN, so no test cases are needed for now. In addition, this patch adds failure test cases where bpf programs cannot pass the verifier due to untrusted pointer arguments. Signed-off-by: Juntong Deng <juntong.deng@xxxxxxxxxxx> --- tools/testing/selftests/bpf/prog_tests/crib.c | 1 + .../testing/selftests/bpf/progs/crib_common.h | 4 ++ .../selftests/bpf/progs/crib_files_failure.c | 22 +++++++++ .../selftests/bpf/progs/crib_files_success.c | 46 +++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/crib.c b/tools/testing/selftests/bpf/prog_tests/crib.c index 48c5156504ad..5ef887e43170 100644 --- a/tools/testing/selftests/bpf/prog_tests/crib.c +++ b/tools/testing/selftests/bpf/prog_tests/crib.c @@ -108,6 +108,7 @@ static void run_files_success_test(const char *prog_name) static const char * const files_success_tests[] = { "test_bpf_iter_task_file", + "test_bpf_fget_task", }; void test_crib(void) diff --git a/tools/testing/selftests/bpf/progs/crib_common.h b/tools/testing/selftests/bpf/progs/crib_common.h index 93b8f9b1bdf8..0bc77d1b02b2 100644 --- a/tools/testing/selftests/bpf/progs/crib_common.h +++ b/tools/testing/selftests/bpf/progs/crib_common.h @@ -18,4 +18,8 @@ extern struct file *bpf_iter_task_file_next(struct bpf_iter_task_file *it) __ksy extern int bpf_iter_task_file_get_fd(struct bpf_iter_task_file *it__iter) __ksym; extern void bpf_iter_task_file_destroy(struct bpf_iter_task_file *it) __ksym; +extern struct file *bpf_fget_task(struct task_struct *task, unsigned int fd) __ksym; +extern unsigned int bpf_get_file_ops_type(struct file *file) __ksym; +extern void bpf_put_file(struct file *file) __ksym; + #endif /* __CRIB_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/crib_files_failure.c b/tools/testing/selftests/bpf/progs/crib_files_failure.c index ebae01d87ff9..9360aad50c15 100644 --- a/tools/testing/selftests/bpf/progs/crib_files_failure.c +++ b/tools/testing/selftests/bpf/progs/crib_files_failure.c @@ -84,3 +84,25 @@ int bpf_iter_task_file_destroy_uninit_iter(void *ctx) return 0; } + +SEC("syscall") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int bpf_fget_task_untrusted_file(void *ctx) +{ + struct task_struct *task = NULL; + + bpf_fget_task(task, 1); + + return 0; +} + +SEC("syscall") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int bpf_get_file_ops_type_untrusted_file(void *ctx) +{ + struct file *file = NULL; + + bpf_get_file_ops_type(file); + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/crib_files_success.c b/tools/testing/selftests/bpf/progs/crib_files_success.c index 8de43dedbb02..f2e8becbfd04 100644 --- a/tools/testing/selftests/bpf/progs/crib_files_success.c +++ b/tools/testing/selftests/bpf/progs/crib_files_success.c @@ -71,3 +71,49 @@ int test_bpf_iter_task_file(void *ctx) bpf_task_release(task); return 0; } + +SEC("syscall") +int test_bpf_fget_task(void *ctx) +{ + struct task_struct *task; + struct file *file; + + task = bpf_task_from_vpid(pid); + if (task == NULL) { + err = 1; + return 0; + } + + file = bpf_fget_task(task, 0); + if (file == NULL) { + err = 2; + goto cleanup; + } + + bpf_put_file(file); + + file = bpf_fget_task(task, 1); + if (file == NULL) { + err = 3; + goto cleanup; + } + + bpf_put_file(file); + + file = bpf_fget_task(task, 2); + if (file == NULL) { + err = 4; + goto cleanup; + } + + bpf_put_file(file); + + file = bpf_fget_task(task, 3); + if (file != NULL) { + err = 5; + bpf_put_file(file); + } +cleanup: + bpf_task_release(task); + return 0; +} -- 2.39.5