Skip to content

Commit 2357672

Browse files
kkdwivediAlexei Starovoitov
authored andcommitted
bpf: Introduce BPF support for kernel module function calls
This change adds support on the kernel side to allow for BPF programs to call kernel module functions. Userspace will prepare an array of module BTF fds that is passed in during BPF_PROG_LOAD using fd_array parameter. In the kernel, the module BTFs are placed in the auxilliary struct for bpf_prog, and loaded as needed. The verifier then uses insn->off to index into the fd_array. insn->off 0 is reserved for vmlinux BTF (for backwards compat), so userspace must use an fd_array index > 0 for module kfunc support. kfunc_btf_tab is sorted based on offset in an array, and each offset corresponds to one descriptor, with a max limit up to 256 such module BTFs. We also change existing kfunc_tab to distinguish each element based on imm, off pair as each such call will now be distinct. Another change is to check_kfunc_call callback, which now include a struct module * pointer, this is to be used in later patch such that the kfunc_id and module pointer are matched for dynamically registered BTF sets from loadable modules, so that same kfunc_id in two modules doesn't lead to check_kfunc_call succeeding. For the duration of the check_kfunc_call, the reference to struct module exists, as it returns the pointer stored in kfunc_btf_tab. Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent d0f1c24 commit 2357672

File tree

6 files changed

+188
-32
lines changed

6 files changed

+188
-32
lines changed

include/linux/bpf.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ struct bpf_verifier_ops {
513513
const struct btf_type *t, int off, int size,
514514
enum bpf_access_type atype,
515515
u32 *next_btf_id);
516-
bool (*check_kfunc_call)(u32 kfunc_btf_id);
516+
bool (*check_kfunc_call)(u32 kfunc_btf_id, struct module *owner);
517517
};
518518

519519
struct bpf_prog_offload_ops {
@@ -877,6 +877,7 @@ struct bpf_prog_aux {
877877
void *jit_data; /* JIT specific data. arch dependent */
878878
struct bpf_jit_poke_descriptor *poke_tab;
879879
struct bpf_kfunc_desc_tab *kfunc_tab;
880+
struct bpf_kfunc_btf_tab *kfunc_btf_tab;
880881
u32 size_poke_tab;
881882
struct bpf_ksym ksym;
882883
const struct bpf_prog_ops *ops;
@@ -1639,7 +1640,7 @@ int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
16391640
int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog,
16401641
const union bpf_attr *kattr,
16411642
union bpf_attr __user *uattr);
1642-
bool bpf_prog_test_check_kfunc_call(u32 kfunc_id);
1643+
bool bpf_prog_test_check_kfunc_call(u32 kfunc_id, struct module *owner);
16431644
bool btf_ctx_access(int off, int size, enum bpf_access_type type,
16441645
const struct bpf_prog *prog,
16451646
struct bpf_insn_access_aux *info);
@@ -1860,7 +1861,8 @@ static inline int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog,
18601861
return -ENOTSUPP;
18611862
}
18621863

1863-
static inline bool bpf_prog_test_check_kfunc_call(u32 kfunc_id)
1864+
static inline bool bpf_prog_test_check_kfunc_call(u32 kfunc_id,
1865+
struct module *owner)
18641866
{
18651867
return false;
18661868
}

include/linux/bpf_verifier.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,5 +527,7 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
527527
const struct bpf_prog *tgt_prog,
528528
u32 btf_id,
529529
struct bpf_attach_target_info *tgt_info);
530+
void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab);
531+
530532

531533
#endif /* _LINUX_BPF_VERIFIER_H */

kernel/bpf/core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/perf_event.h>
3333
#include <linux/extable.h>
3434
#include <linux/log2.h>
35+
#include <linux/bpf_verifier.h>
3536

3637
#include <asm/barrier.h>
3738
#include <asm/unaligned.h>
@@ -2255,6 +2256,9 @@ static void bpf_prog_free_deferred(struct work_struct *work)
22552256
int i;
22562257

22572258
aux = container_of(work, struct bpf_prog_aux, work);
2259+
#ifdef CONFIG_BPF_SYSCALL
2260+
bpf_free_kfunc_btf_tab(aux->kfunc_btf_tab);
2261+
#endif
22582262
bpf_free_used_maps(aux);
22592263
bpf_free_used_btfs(aux);
22602264
if (bpf_prog_is_dev_bound(aux))

0 commit comments

Comments
 (0)