// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Red Hat, Inc. */
#include <test_progs.h>
#include "fentry_recursive.skel.h"
#include "fentry_recursive_target.skel.h"
#include <bpf/btf.h>
#include "bpf/libbpf_internal.h"

/* Test recursive attachment of tracing progs with more than one nesting level
 * is not possible. Create a chain of attachment, verify that the last prog
 * will fail. Depending on the arguments, following cases are tested:
 *
 * - Recursive loading of tracing progs, without attaching (attach = false,
 *   detach = false). The chain looks like this:
 *       load target
 *       load fentry1 -> target
 *       load fentry2 -> fentry1 (fail)
 *
 * - Recursive attach of tracing progs (attach = true, detach = false). The
 *   chain looks like this:
 *       load target
 *       load fentry1 -> target
 *       attach fentry1 -> target
 *       load fentry2 -> fentry1 (fail)
 *
 * - Recursive attach and detach of tracing progs (attach = true, detach =
 *   true). This validates that attach_tracing_prog flag will be set throughout
 *   the whole lifecycle of an fentry prog, independently from whether it's
 *   detached. The chain looks like this:
 *       load target
 *       load fentry1 -> target
 *       attach fentry1 -> target
 *       detach fentry1
 *       load fentry2 -> fentry1 (fail)
 */
static void test_recursive_fentry_chain(bool attach, bool detach)
{
	struct fentry_recursive_target *target_skel = NULL;
	struct fentry_recursive *tracing_chain[2] = {};
	struct bpf_program *prog;
	int prev_fd, err;

	target_skel = fentry_recursive_target__open_and_load();
	if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))
		return;

	/* Create an attachment chain with two fentry progs */
	for (int i = 0; i < 2; i++) {
		tracing_chain[i] = fentry_recursive__open();
		if (!ASSERT_OK_PTR(tracing_chain[i], "fentry_recursive__open"))
			goto close_prog;

		/* The first prog in the chain is going to be attached to the target
		 * fentry program, the second one to the previous in the chain.
		 */
		prog = tracing_chain[i]->progs.recursive_attach;
		if (i == 0) {
			prev_fd = bpf_program__fd(target_skel->progs.test1);
			err = bpf_program__set_attach_target(prog, prev_fd, "test1");
		} else {
			prev_fd = bpf_program__fd(tracing_chain[i-1]->progs.recursive_attach);
			err = bpf_program__set_attach_target(prog, prev_fd, "recursive_attach");
		}

		if (!ASSERT_OK(err, "bpf_program__set_attach_target"))
			goto close_prog;

		err = fentry_recursive__load(tracing_chain[i]);
		/* The first attach should succeed, the second fail */
		if (i == 0) {
			if (!ASSERT_OK(err, "fentry_recursive__load"))
				goto close_prog;

			if (attach) {
				err = fentry_recursive__attach(tracing_chain[i]);
				if (!ASSERT_OK(err, "fentry_recursive__attach"))
					goto close_prog;
			}

			if (detach) {
				/* Flag attach_tracing_prog should still be set, preventing
				 * attachment of the following prog.
				 */
				fentry_recursive__detach(tracing_chain[i]);
			}
		} else {
			if (!ASSERT_ERR(err, "fentry_recursive__load"))
				goto close_prog;
		}
	}

close_prog:
	fentry_recursive_target__destroy(target_skel);
	for (int i = 0; i < 2; i++) {
		fentry_recursive__destroy(tracing_chain[i]);
	}
}

void test_recursive_fentry(void)
{
	if (test__start_subtest("attach"))
		test_recursive_fentry_chain(true, false);
	if (test__start_subtest("load"))
		test_recursive_fentry_chain(false, false);
	if (test__start_subtest("detach"))
		test_recursive_fentry_chain(true, true);
}

/* Test that a tracing prog reattachment (when we land in
 * "prog->aux->dst_trampoline and tgt_prog is NULL" branch in
 * bpf_tracing_prog_attach) does not lead to a crash due to missing attach_btf
 */
void test_fentry_attach_btf_presence(void)
{
	struct fentry_recursive_target *target_skel = NULL;
	struct fentry_recursive *tracing_skel = NULL;
	struct bpf_program *prog;
	int err, link_fd, tgt_prog_fd;

	target_skel = fentry_recursive_target__open_and_load();
	if (!ASSERT_OK_PTR(target_skel, "fentry_recursive_target__open_and_load"))
		goto close_prog;

	tracing_skel = fentry_recursive__open();
	if (!ASSERT_OK_PTR(tracing_skel, "fentry_recursive__open"))
		goto close_prog;

	prog = tracing_skel->progs.recursive_attach;
	tgt_prog_fd = bpf_program__fd(target_skel->progs.fentry_target);
	err = bpf_program__set_attach_target(prog, tgt_prog_fd, "fentry_target");
	if (!ASSERT_OK(err, "bpf_program__set_attach_target"))
		goto close_prog;

	err = fentry_recursive__load(tracing_skel);
	if (!ASSERT_OK(err, "fentry_recursive__load"))
		goto close_prog;

	tgt_prog_fd = bpf_program__fd(tracing_skel->progs.recursive_attach);
	link_fd = bpf_link_create(tgt_prog_fd, 0, BPF_TRACE_FENTRY, NULL);
	if (!ASSERT_GE(link_fd, 0, "link_fd"))
		goto close_prog;

	fentry_recursive__detach(tracing_skel);

	err = fentry_recursive__attach(tracing_skel);
	ASSERT_ERR(err, "fentry_recursive__attach");

close_prog:
	fentry_recursive_target__destroy(target_skel);
	fentry_recursive__destroy(tracing_skel);
}
