tools/testing/selftests/bpf/progs/task_kfunc_success.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/task_kfunc_success.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/task_kfunc_success.c
Extension
.c
Size
8458 bytes
Lines
419
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */

#include <vmlinux.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>

#include "../bpf_experimental.h"
#include "task_kfunc_common.h"

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

int err, pid;

/* Prototype for all of the program trace events below:
 *
 * TRACE_EVENT(task_newtask,
 *         TP_PROTO(struct task_struct *p, u64 clone_flags)
 */

struct task_struct *bpf_task_acquire(struct task_struct *p) __ksym __weak;

struct task_struct *bpf_task_acquire___one(struct task_struct *task) __ksym __weak;
/* The two-param bpf_task_acquire doesn't exist */
struct task_struct *bpf_task_acquire___two(struct task_struct *p, void *ctx) __ksym __weak;
/* Incorrect type for first param */
struct task_struct *bpf_task_acquire___three(void *ctx) __ksym __weak;

void invalid_kfunc(void) __ksym __weak;
void bpf_testmod_test_mod_kfunc(int i) __ksym __weak;

static bool is_test_kfunc_task(void)
{
	int cur_pid = bpf_get_current_pid_tgid() >> 32;

	return pid == cur_pid;
}

static int test_acquire_release(struct task_struct *task)
{
	struct task_struct *acquired = NULL;

	if (!bpf_ksym_exists(bpf_task_acquire)) {
		err = 3;
		return 0;
	}
	if (!bpf_ksym_exists(bpf_testmod_test_mod_kfunc)) {
		err = 4;
		return 0;
	}
	if (bpf_ksym_exists(invalid_kfunc)) {
		/* the verifier's dead code elimination should remove this */
		err = 5;
		asm volatile ("goto -1"); /* for (;;); */
	}

	acquired = bpf_task_acquire(task);
	if (acquired)
		bpf_task_release(acquired);
	else
		err = 6;

	return 0;
}

SEC("tp_btf/task_newtask")
int BPF_PROG(test_task_kfunc_flavor_relo, struct task_struct *task, u64 clone_flags)
{
	struct task_struct *acquired = NULL;
	int fake_ctx = 42;

	if (bpf_ksym_exists(bpf_task_acquire___one)) {
		acquired = bpf_task_acquire___one(task);
	} else if (bpf_ksym_exists(bpf_task_acquire___two)) {
		/* Here, bpf_object__resolve_ksym_func_btf_id's find_ksym_btf_id
		 * call will find vmlinux's bpf_task_acquire, but subsequent
		 * bpf_core_types_are_compat will fail
		 */
		acquired = bpf_task_acquire___two(task, &fake_ctx);
		err = 3;
		return 0;
	} else if (bpf_ksym_exists(bpf_task_acquire___three)) {
		/* bpf_core_types_are_compat will fail similarly to above case */
		acquired = bpf_task_acquire___three(&fake_ctx);
		err = 4;
		return 0;
	}

	if (acquired)
		bpf_task_release(acquired);

Annotation

Implementation Notes