Skip to content

Commit

Permalink
selftests/bpf: Add tests for bpf_fget_task() kfunc
Browse files Browse the repository at this point in the history
This patch adds test cases for bpf_fget_task() kfunc.

test_bpf_fget_task is used to test obtaining struct file based on
the file descriptor in the current process.

bpf_fget_task_null_task and bpf_fget_task_untrusted_task are used to
test the failure cases of passing NULL or untrusted pointer as argument.

Signed-off-by: Juntong Deng <[email protected]>
  • Loading branch information
juntongdeng authored and Kernel Patches Daemon committed Nov 21, 2024
1 parent 570861d commit b77bfa1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tools/testing/selftests/bpf/bpf_experimental.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ extern void bpf_put_file(struct file *file) __ksym;
*/
extern int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz) __ksym;

/* Description
* Get a pointer to the struct file corresponding to the task file descriptor
* Note that this function acquires a reference to struct file.
* Returns
* The corresponding struct file pointer if found, otherwise returns NULL
*/
extern struct file *bpf_fget_task(struct task_struct *task, unsigned int fd) __ksym;

/* This macro must be used to mark the exception callback corresponding to the
* main program. For example:
*
Expand Down
46 changes: 46 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/fs_kfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <test_progs.h>
#include "test_get_xattr.skel.h"
#include "test_fsverity.skel.h"
#include "test_fget_task.skel.h"
#include "fs_kfuncs_failure.skel.h"

static const char testfile[] = "/tmp/test_progs_fs_kfuncs";

Expand Down Expand Up @@ -139,11 +141,55 @@ static void test_fsverity(void)
remove(testfile);
}

static void test_fget_task(void)
{
int pipefd[2], prog_fd, err = 0;
struct test_fget_task *skel;
struct bpf_program *prog;

skel = test_fget_task__open_and_load();
if (!ASSERT_OK_PTR(skel, "open_and_load"))
return;

if (!ASSERT_OK(skel->bss->err, "pre_test_err"))
goto cleanup_skel;

prog = bpf_object__find_program_by_name(skel->obj, "test_bpf_fget_task");
if (!ASSERT_OK_PTR(prog, "find_program_by_name"))
goto cleanup_skel;

prog_fd = bpf_program__fd(prog);
if (!ASSERT_GT(prog_fd, -1, "bpf_program__fd"))
goto cleanup_skel;

if (pipe(pipefd) < 0)
goto cleanup_skel;

skel->bss->test_fd1 = pipefd[0];
skel->bss->test_fd2 = pipefd[1];

err = bpf_prog_test_run_opts(prog_fd, NULL);
if (!ASSERT_OK(err, "prog_test_run"))
goto cleanup_pipe;

ASSERT_OK(skel->bss->err, "run_bpf_fget_task_test_failure");
cleanup_pipe:
close(pipefd[0]);
close(pipefd[1]);
cleanup_skel:
test_fget_task__destroy(skel);
}

void test_fs_kfuncs(void)
{
if (test__start_subtest("xattr"))
test_xattr();

if (test__start_subtest("fsverity"))
test_fsverity();

if (test__start_subtest("fget_task"))
test_fget_task();

RUN_TESTS(fs_kfuncs_failure);
}
33 changes: 33 additions & 0 deletions tools/testing/selftests/bpf/progs/fs_kfuncs_failure.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0

#include "vmlinux.h"
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"

char _license[] SEC("license") = "GPL";

SEC("syscall")
__failure __msg("Possibly NULL pointer passed to trusted arg0")
int bpf_fget_task_null_task(void *ctx)
{
struct task_struct *task = NULL;

bpf_fget_task(task, 1);

return 0;
}

SEC("syscall")
__failure __msg("R1 must be referenced or trusted")
int bpf_fget_task_untrusted_task(void *ctx)
{
struct task_struct *task;

task = bpf_get_current_task_btf()->parent;

bpf_fget_task(task, 1);

return 0;
}
49 changes: 49 additions & 0 deletions tools/testing/selftests/bpf/progs/test_fget_task.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0

#include "vmlinux.h"
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"
#include "task_kfunc_common.h"

char _license[] SEC("license") = "GPL";

int err, test_fd1, test_fd2;

SEC("syscall")
int test_bpf_fget_task(void *ctx)
{
struct task_struct *task;
struct file *file;

task = bpf_get_current_task_btf();
if (task == NULL) {
err = 1;
return 0;
}

file = bpf_fget_task(task, test_fd1);
if (file == NULL) {
err = 2;
return 0;
}

bpf_put_file(file);

file = bpf_fget_task(task, test_fd2);
if (file == NULL) {
err = 3;
return 0;
}

bpf_put_file(file);

file = bpf_fget_task(task, 9999);
if (file != NULL) {
err = 4;
bpf_put_file(file);
}

return 0;
}

0 comments on commit b77bfa1

Please sign in to comment.