Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/
  3
  4#define _GNU_SOURCE
  5#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 = 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 = 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}
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.*/
  3
  4#define _GNU_SOURCE
  5#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.no_lock, true);
 29	bpf_program__set_autoload(skel->progs.two_regions, true);
 30	bpf_program__set_autoload(skel->progs.non_sleepable_1, true);
 31	bpf_program__set_autoload(skel->progs.non_sleepable_2, true);
 
 
 
 
 
 32	err = rcu_read_lock__load(skel);
 33	if (!ASSERT_OK(err, "skel_load"))
 34		goto out;
 35
 36	err = rcu_read_lock__attach(skel);
 37	if (!ASSERT_OK(err, "skel_attach"))
 38		goto out;
 39
 40	syscall(SYS_getpgid);
 41
 42	ASSERT_EQ(skel->bss->task_storage_val, 2, "task_storage_val");
 43	ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id");
 44out:
 45	rcu_read_lock__destroy(skel);
 46}
 47
 48static void test_rcuptr_acquire(void)
 49{
 50	struct rcu_read_lock *skel;
 51	int err;
 52
 53	skel = rcu_read_lock__open();
 54	if (!ASSERT_OK_PTR(skel, "skel_open"))
 55		return;
 56
 57	skel->bss->target_pid = syscall(SYS_gettid);
 58
 59	bpf_program__set_autoload(skel->progs.task_acquire, true);
 60	err = rcu_read_lock__load(skel);
 61	if (!ASSERT_OK(err, "skel_load"))
 62		goto out;
 63
 64	err = rcu_read_lock__attach(skel);
 65	ASSERT_OK(err, "skel_attach");
 66out:
 67	rcu_read_lock__destroy(skel);
 68}
 69
 70static const char * const inproper_region_tests[] = {
 71	"miss_lock",
 
 72	"miss_unlock",
 73	"non_sleepable_rcu_mismatch",
 74	"inproper_sleepable_helper",
 75	"inproper_sleepable_kfunc",
 76	"nested_rcu_region",
 
 
 77};
 78
 79static void test_inproper_region(void)
 80{
 81	struct rcu_read_lock *skel;
 82	struct bpf_program *prog;
 83	int i, err;
 84
 85	for (i = 0; i < ARRAY_SIZE(inproper_region_tests); i++) {
 86		skel = rcu_read_lock__open();
 87		if (!ASSERT_OK_PTR(skel, "skel_open"))
 88			return;
 89
 90		prog = bpf_object__find_program_by_name(skel->obj, inproper_region_tests[i]);
 91		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
 92			goto out;
 93		bpf_program__set_autoload(prog, true);
 94		err = rcu_read_lock__load(skel);
 95		ASSERT_ERR(err, "skel_load");
 96out:
 97		rcu_read_lock__destroy(skel);
 98	}
 99}
100
101static const char * const rcuptr_misuse_tests[] = {
102	"task_untrusted_non_rcuptr",
103	"task_untrusted_rcuptr",
104	"cross_rcu_region",
105};
106
107static void test_rcuptr_misuse(void)
108{
109	struct rcu_read_lock *skel;
110	struct bpf_program *prog;
111	int i, err;
112
113	for (i = 0; i < ARRAY_SIZE(rcuptr_misuse_tests); i++) {
114		skel = rcu_read_lock__open();
115		if (!ASSERT_OK_PTR(skel, "skel_open"))
116			return;
117
118		prog = bpf_object__find_program_by_name(skel->obj, rcuptr_misuse_tests[i]);
119		if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
120			goto out;
121		bpf_program__set_autoload(prog, true);
122		err = rcu_read_lock__load(skel);
123		ASSERT_ERR(err, "skel_load");
124out:
125		rcu_read_lock__destroy(skel);
126	}
127}
128
129void test_rcu_read_lock(void)
130{
131	struct btf *vmlinux_btf;
132	int cgroup_fd;
133
134	vmlinux_btf = btf__load_vmlinux_btf();
135	if (!ASSERT_OK_PTR(vmlinux_btf, "could not load vmlinux BTF"))
136		return;
137	if (btf__find_by_name_kind(vmlinux_btf, "rcu", BTF_KIND_TYPE_TAG) < 0) {
138		test__skip();
139		goto out;
140	}
141
142	cgroup_fd = test__join_cgroup("/rcu_read_lock");
143	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /rcu_read_lock"))
144		goto out;
145
146	cgroup_id = get_cgroup_id("/rcu_read_lock");
147	if (test__start_subtest("success"))
148		test_success();
149	if (test__start_subtest("rcuptr_acquire"))
150		test_rcuptr_acquire();
151	if (test__start_subtest("negative_tests_inproper_region"))
152		test_inproper_region();
153	if (test__start_subtest("negative_tests_rcuptr_misuse"))
154		test_rcuptr_misuse();
155	close(cgroup_fd);
156out:
157	btf__free(vmlinux_btf);
158}