KFunc bpf_get_kmem_cache
This function returns slab cache information from a virtual address of a slab object.
Definition
This function returns slab cache information from a virtual address of a slab object.
It doesn't grab a reference count of the kmem_cache so the caller is responsible to manage the access. The returned point is marked as PTR_UNTRUSTED.
Parameters
addr: virtual address of the slab object
Returns
A valid kmem_cache pointer, otherwise NULL.
Signature
struct kmem_cache *bpf_get_kmem_cache(u64 addr)
Usage
This kfunc has many possible use cases. One example is its usage by perf to resolve names of slab objects, when used in combination with a slab allocator iterator(iter/kmem_cache). see: commit
Program types
The following program types can make use of this kfunc:
BPF_PROG_TYPE_CGROUP_DEVICEv6.12 -BPF_PROG_TYPE_CGROUP_SKBBPF_PROG_TYPE_CGROUP_SOCKv6.12 -BPF_PROG_TYPE_CGROUP_SOCKOPTv6.12 -BPF_PROG_TYPE_CGROUP_SOCK_ADDRv6.7 -BPF_PROG_TYPE_CGROUP_SYSCTLv6.12 -BPF_PROG_TYPE_LSMBPF_PROG_TYPE_LWT_INBPF_PROG_TYPE_LWT_OUTBPF_PROG_TYPE_LWT_SEG6LOCALBPF_PROG_TYPE_LWT_XMITBPF_PROG_TYPE_NETFILTERBPF_PROG_TYPE_PERF_EVENTv6.12 -BPF_PROG_TYPE_SCHED_ACTBPF_PROG_TYPE_SCHED_CLSBPF_PROG_TYPE_SK_SKBBPF_PROG_TYPE_SOCKET_FILTERBPF_PROG_TYPE_SOCK_OPSv6.15 -BPF_PROG_TYPE_STRUCT_OPSBPF_PROG_TYPE_SYSCALLBPF_PROG_TYPE_TRACEPOINTv6.12 -BPF_PROG_TYPE_TRACINGBPF_PROG_TYPE_XDP
Example
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024 Google */
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "bpf_experimental.h"
char _license[] SEC("license") = "GPL";
#define SLAB_NAME_MAX 32
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(void *));
__uint(value_size, SLAB_NAME_MAX);
__uint(max_entries, 1);
} slab_hash SEC(".maps");
extern struct kmem_cache *bpf_get_kmem_cache(u64 addr) __ksym;
/* Result, will be checked by userspace */
int task_struct_found;
SEC("raw_tp/bpf_test_finish")
int BPF_PROG(check_task_struct)
{
u64 curr = bpf_get_current_task();
struct kmem_cache *s;
char *name;
s = bpf_get_kmem_cache(curr);
if (s == NULL) {
task_struct_found = -1;
return 0;
}
name = bpf_map_lookup_elem(&slab_hash, &s);
if (name && !bpf_strncmp(name, 11, "task_struct"))
task_struct_found = 1;
else
task_struct_found = -2;
return 0;
}