155 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/3 4#define _GNU_SOURCE5#include <unistd.h>6#include <sys/syscall.h>7#include <sys/types.h>8#include <test_progs.h>9#include <bpf/btf.h>10#include "rcu_read_lock.skel.h"11#include "cgroup_helpers.h"12 13static unsigned long long cgroup_id;14 15static void test_success(void)16{17 struct rcu_read_lock *skel;18 int err;19 20 skel = rcu_read_lock__open();21 if (!ASSERT_OK_PTR(skel, "skel_open"))22 return;23 24 skel->bss->target_pid = syscall(SYS_gettid);25 26 bpf_program__set_autoload(skel->progs.get_cgroup_id, true);27 bpf_program__set_autoload(skel->progs.task_succ, true);28 bpf_program__set_autoload(skel->progs.two_regions, true);29 bpf_program__set_autoload(skel->progs.non_sleepable_1, true);30 bpf_program__set_autoload(skel->progs.non_sleepable_2, true);31 bpf_program__set_autoload(skel->progs.task_trusted_non_rcuptr, true);32 bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog, true);33 bpf_program__set_autoload(skel->progs.rcu_read_lock_global_subprog, true);34 bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_lock, true);35 bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_unlock, true);36 err = rcu_read_lock__load(skel);37 if (!ASSERT_OK(err, "skel_load"))38 goto out;39 40 err = rcu_read_lock__attach(skel);41 if (!ASSERT_OK(err, "skel_attach"))42 goto out;43 44 syscall(SYS_getpgid);45 46 ASSERT_EQ(skel->bss->task_storage_val, 2, "task_storage_val");47 ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");48out:49 rcu_read_lock__destroy(skel);50}51 52static void test_rcuptr_acquire(void)53{54 struct rcu_read_lock *skel;55 int err;56 57 skel = rcu_read_lock__open();58 if (!ASSERT_OK_PTR(skel, "skel_open"))59 return;60 61 skel->bss->target_pid = syscall(SYS_gettid);62 63 bpf_program__set_autoload(skel->progs.task_acquire, true);64 err = rcu_read_lock__load(skel);65 if (!ASSERT_OK(err, "skel_load"))66 goto out;67 68 err = rcu_read_lock__attach(skel);69 ASSERT_OK(err, "skel_attach");70out:71 rcu_read_lock__destroy(skel);72}73 74static const char * const inproper_region_tests[] = {75 "miss_lock",76 "no_lock",77 "miss_unlock",78 "non_sleepable_rcu_mismatch",79 "inproper_sleepable_helper",80 "inproper_sleepable_kfunc",81 "nested_rcu_region",82 "rcu_read_lock_global_subprog_lock",83 "rcu_read_lock_global_subprog_unlock",84};85 86static void test_inproper_region(void)87{88 struct rcu_read_lock *skel;89 struct bpf_program *prog;90 int i, err;91 92 for (i = 0; i < ARRAY_SIZE(inproper_region_tests); i++) {93 skel = rcu_read_lock__open();94 if (!ASSERT_OK_PTR(skel, "skel_open"))95 return;96 97 prog = bpf_object__find_program_by_name(skel->obj, inproper_region_tests[i]);98 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))99 goto out;100 bpf_program__set_autoload(prog, true);101 err = rcu_read_lock__load(skel);102 ASSERT_ERR(err, "skel_load");103out:104 rcu_read_lock__destroy(skel);105 }106}107 108static const char * const rcuptr_misuse_tests[] = {109 "task_untrusted_rcuptr",110 "cross_rcu_region",111};112 113static void test_rcuptr_misuse(void)114{115 struct rcu_read_lock *skel;116 struct bpf_program *prog;117 int i, err;118 119 for (i = 0; i < ARRAY_SIZE(rcuptr_misuse_tests); i++) {120 skel = rcu_read_lock__open();121 if (!ASSERT_OK_PTR(skel, "skel_open"))122 return;123 124 prog = bpf_object__find_program_by_name(skel->obj, rcuptr_misuse_tests[i]);125 if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))126 goto out;127 bpf_program__set_autoload(prog, true);128 err = rcu_read_lock__load(skel);129 ASSERT_ERR(err, "skel_load");130out:131 rcu_read_lock__destroy(skel);132 }133}134 135void test_rcu_read_lock(void)136{137 int cgroup_fd;138 139 cgroup_fd = test__join_cgroup("/rcu_read_lock");140 if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /rcu_read_lock"))141 goto out;142 143 cgroup_id = get_cgroup_id("/rcu_read_lock");144 if (test__start_subtest("success"))145 test_success();146 if (test__start_subtest("rcuptr_acquire"))147 test_rcuptr_acquire();148 if (test__start_subtest("negative_tests_inproper_region"))149 test_inproper_region();150 if (test__start_subtest("negative_tests_rcuptr_misuse"))151 test_rcuptr_misuse();152 close(cgroup_fd);153out:;154}155