diff mbox series

[v18,02/13] btf: Export bpf_dynptr definition

Message ID 20220920075951.929132-3-roberto.sassu@huaweicloud.com (mailing list archive)
State Accepted
Commit 00f146413ccb6c84308e559281449755c83f54c5
Headers show
Series bpf: Add kfuncs for PKCS#7 signature verification | expand

Commit Message

Roberto Sassu Sept. 20, 2022, 7:59 a.m. UTC
From: Roberto Sassu <roberto.sassu@huawei.com>

eBPF dynamic pointers is a new feature recently added to upstream. It binds
together a pointer to a memory area and its size. The internal kernel
structure bpf_dynptr_kern is not accessible by eBPF programs in user space.
They instead see bpf_dynptr, which is then translated to the internal
kernel structure by the eBPF verifier.

The problem is that it is not possible to include at the same time the uapi
include linux/bpf.h and the vmlinux BTF vmlinux.h, as they both contain the
definition of some structures/enums. The compiler complains saying that the
structures/enums are redefined.

As bpf_dynptr is defined in the uapi include linux/bpf.h, this makes it
impossible to include vmlinux.h. However, in some cases, e.g. when using
kfuncs, vmlinux.h has to be included. The only option until now was to
include vmlinux.h and add the definition of bpf_dynptr directly in the eBPF
program source code from linux/bpf.h.

Solve the problem by using the same approach as for bpf_timer (which also
follows the same scheme with the _kern suffix for the internal kernel
structure).

Add the following line in one of the dynamic pointer helpers,
bpf_dynptr_from_mem():

BTF_TYPE_EMIT(struct bpf_dynptr);

Cc: stable@vger.kernel.org
Cc: Joanne Koong <joannelkoong@gmail.com>
Fixes: 97e03f521050c ("bpf: Add verifier support for dynptrs")
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Acked-by: Yonghong Song <yhs@fb.com>
---
 kernel/bpf/helpers.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

KP Singh Sept. 21, 2022, 1:43 p.m. UTC | #1
On Tue, Sep 20, 2022 at 10:01 AM Roberto Sassu
<roberto.sassu@huaweicloud.com> wrote:
>
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> eBPF dynamic pointers is a new feature recently added to upstream. It binds
> together a pointer to a memory area and its size. The internal kernel
> structure bpf_dynptr_kern is not accessible by eBPF programs in user space.
> They instead see bpf_dynptr, which is then translated to the internal
> kernel structure by the eBPF verifier.
>
> The problem is that it is not possible to include at the same time the uapi
> include linux/bpf.h and the vmlinux BTF vmlinux.h, as they both contain the
> definition of some structures/enums. The compiler complains saying that the
> structures/enums are redefined.
>
> As bpf_dynptr is defined in the uapi include linux/bpf.h, this makes it
> impossible to include vmlinux.h. However, in some cases, e.g. when using
> kfuncs, vmlinux.h has to be included. The only option until now was to
> include vmlinux.h and add the definition of bpf_dynptr directly in the eBPF
> program source code from linux/bpf.h.
>
> Solve the problem by using the same approach as for bpf_timer (which also
> follows the same scheme with the _kern suffix for the internal kernel
> structure).
>
> Add the following line in one of the dynamic pointer helpers,
> bpf_dynptr_from_mem():
>
> BTF_TYPE_EMIT(struct bpf_dynptr);
>
> Cc: stable@vger.kernel.org
> Cc: Joanne Koong <joannelkoong@gmail.com>
> Fixes: 97e03f521050c ("bpf: Add verifier support for dynptrs")
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Acked-by: Yonghong Song <yhs@fb.com>

I tested this out and it works, however for the BPF signing use case
where "bpf_dynptr_kern" is added to struct bpf_prog_aux one still
ends up defining the __ksym extern with bpf_dynptr_kern.

But let's discuss that when the series is posted.

Tested-by: KP Singh <kpsingh@kernel.org>
diff mbox series

Patch

diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 41aeaf3862ec..7ce1f583b929 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -1446,6 +1446,8 @@  BPF_CALL_4(bpf_dynptr_from_mem, void *, data, u32, size, u64, flags, struct bpf_
 {
 	int err;
 
+	BTF_TYPE_EMIT(struct bpf_dynptr);
+
 	err = bpf_dynptr_check_size(size);
 	if (err)
 		goto error;