brintos

brintos / linux-shallow public Read only

0
0
Text · 4.9 KiB · 8100509 Raw
152 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2023 Red Hat, Inc. */3#include <test_progs.h>4#include "fentry_recursive.skel.h"5#include "fentry_recursive_target.skel.h"6#include <bpf/btf.h>7#include "bpf/libbpf_internal.h"8 9/* Test recursive attachment of tracing progs with more than one nesting level10 * is not possible. Create a chain of attachment, verify that the last prog11 * will fail. Depending on the arguments, following cases are tested:12 *13 * - Recursive loading of tracing progs, without attaching (attach = false,14 *   detach = false). The chain looks like this:15 *       load target16 *       load fentry1 -> target17 *       load fentry2 -> fentry1 (fail)18 *19 * - Recursive attach of tracing progs (attach = true, detach = false). The20 *   chain looks like this:21 *       load target22 *       load fentry1 -> target23 *       attach fentry1 -> target24 *       load fentry2 -> fentry1 (fail)25 *26 * - Recursive attach and detach of tracing progs (attach = true, detach =27 *   true). This validates that attach_tracing_prog flag will be set throughout28 *   the whole lifecycle of an fentry prog, independently from whether it's29 *   detached. The chain looks like this:30 *       load target31 *       load fentry1 -> target32 *       attach fentry1 -> target33 *       detach fentry134 *       load fentry2 -> fentry1 (fail)35 */36static void test_recursive_fentry_chain(bool attach, bool detach)37{38	struct fentry_recursive_target *target_skel = NULL;39	struct fentry_recursive *tracing_chain[2] = {};40	struct bpf_program *prog;41	int prev_fd, err;42 43	target_skel = fentry_recursive_target__open_and_load();44	if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))45		return;46 47	/* Create an attachment chain with two fentry progs */48	for (int i = 0; i < 2; i++) {49		tracing_chain[i] = fentry_recursive__open();50		if (!ASSERT_OK_PTR(tracing_chain[i], "fentry_recursive__open"))51			goto close_prog;52 53		/* The first prog in the chain is going to be attached to the target54		 * fentry program, the second one to the previous in the chain.55		 */56		prog = tracing_chain[i]->progs.recursive_attach;57		if (i == 0) {58			prev_fd = bpf_program__fd(target_skel->progs.test1);59			err = bpf_program__set_attach_target(prog, prev_fd, "test1");60		} else {61			prev_fd = bpf_program__fd(tracing_chain[i-1]->progs.recursive_attach);62			err = bpf_program__set_attach_target(prog, prev_fd, "recursive_attach");63		}64 65		if (!ASSERT_OK(err, "bpf_program__set_attach_target"))66			goto close_prog;67 68		err = fentry_recursive__load(tracing_chain[i]);69		/* The first attach should succeed, the second fail */70		if (i == 0) {71			if (!ASSERT_OK(err, "fentry_recursive__load"))72				goto close_prog;73 74			if (attach) {75				err = fentry_recursive__attach(tracing_chain[i]);76				if (!ASSERT_OK(err, "fentry_recursive__attach"))77					goto close_prog;78			}79 80			if (detach) {81				/* Flag attach_tracing_prog should still be set, preventing82				 * attachment of the following prog.83				 */84				fentry_recursive__detach(tracing_chain[i]);85			}86		} else {87			if (!ASSERT_ERR(err, "fentry_recursive__load"))88				goto close_prog;89		}90	}91 92close_prog:93	fentry_recursive_target__destroy(target_skel);94	for (int i = 0; i < 2; i++) {95		fentry_recursive__destroy(tracing_chain[i]);96	}97}98 99void test_recursive_fentry(void)100{101	if (test__start_subtest("attach"))102		test_recursive_fentry_chain(true, false);103	if (test__start_subtest("load"))104		test_recursive_fentry_chain(false, false);105	if (test__start_subtest("detach"))106		test_recursive_fentry_chain(true, true);107}108 109/* Test that a tracing prog reattachment (when we land in110 * "prog->aux->dst_trampoline and tgt_prog is NULL" branch in111 * bpf_tracing_prog_attach) does not lead to a crash due to missing attach_btf112 */113void test_fentry_attach_btf_presence(void)114{115	struct fentry_recursive_target *target_skel = NULL;116	struct fentry_recursive *tracing_skel = NULL;117	struct bpf_program *prog;118	int err, link_fd, tgt_prog_fd;119 120	target_skel = fentry_recursive_target__open_and_load();121	if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))122		goto close_prog;123 124	tracing_skel = fentry_recursive__open();125	if (!ASSERT_OK_PTR(tracing_skel, "fentry_recursive__open"))126		goto close_prog;127 128	prog = tracing_skel->progs.recursive_attach;129	tgt_prog_fd = bpf_program__fd(target_skel->progs.fentry_target);130	err = bpf_program__set_attach_target(prog, tgt_prog_fd, "fentry_target");131	if (!ASSERT_OK(err, "bpf_program__set_attach_target"))132		goto close_prog;133 134	err = fentry_recursive__load(tracing_skel);135	if (!ASSERT_OK(err, "fentry_recursive__load"))136		goto close_prog;137 138	tgt_prog_fd = bpf_program__fd(tracing_skel->progs.recursive_attach);139	link_fd = bpf_link_create(tgt_prog_fd, 0, BPF_TRACE_FENTRY, NULL);140	if (!ASSERT_GE(link_fd, 0, "link_fd"))141		goto close_prog;142 143	fentry_recursive__detach(tracing_skel);144 145	err = fentry_recursive__attach(tracing_skel);146	ASSERT_ERR(err, "fentry_recursive__attach");147 148close_prog:149	fentry_recursive_target__destroy(target_skel);150	fentry_recursive__destroy(tracing_skel);151}152