bpf: Allow arena pointers in by-value returns - #13457
bpf: Allow arena pointers in by-value returns#13457kernel-patches-daemon-bpf[bot] wants to merge 10 commits into
Conversation
|
Upstream branch: 1555de3 |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
|
Forwarding comment 5417260118 via email |
|
Forwarding comment 5417271822 via email |
|
Forwarding comment 5417275968 via email |
|
Forwarding comment 5417312123 via email |
|
Forwarding comment 5417327244 via email |
|
Forwarding comment 5417376510 via email |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
|
Forwarding comment 5417461291 via email |
f8c8078 to
be2aea4
Compare
A subprogram returning more than 8 bytes comes back in the R0:R2 register pair, and prepare_func_exit() copies both registers into the caller. The diagnostic modification scope around that copy names only R0, so the write into R2 is never recorded. Fix it by opening a diagnostic modification scope for each return register. This way, both return registers are recorded. Fixes: 0630ad0 ("bpf: Add verifier support for 16-byte returns in R0: R2") Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
btf_type_is_scalar_struct() recurses into nested struct members and carries the nesting depth in a @rec argument, so every caller has to spell out the 0 that starts the walk. Move the recursion into a static helper that keeps @rec and leave btf_type_is_scalar_struct() as a thin wrapper over it, so callers only name the type they are asking about. No functional change. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Simplify btf_scan_type_tags() and added a new helper btf_type_is_arena_ptr(). No functional change. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Use btf_struct_is_composed_of() instead of btf_type_is_scalar_struct() in btf.c so in the future, non scalar member (e.g. arena pointer) can be supported as well. There is no functional change. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
A kfunc that returns a struct by value may only return scalars, and the
message that rejects one names the type but not the member at fault:
kernel function bpf_kfunc_call_test_ret_ptr returns STRUCT
prog_test_ret_ptr that is not composed of scalars
For a large struct that leaves the reader to find the offending member
by inspection. Record the member that made the walk fail and name it, so
the verifier also dumps:
member 'p' has type PTR
What is recorded is a path rather than a single member, because the walk
descends up to 4 levels. For
struct outer { struct inner { void *p; } in; __u64 tag; };
naming 'p' alone would send the reader looking for a member struct outer
does not have, so the message reads "member 'in.p' has type PTR".
The detailed diagnostics for this failure:
Verification failed: Program Structure: Unsupported kernel function
return type
Reason:
bpf_kfunc_call_test_ret_ptr() returns STRUCT prog_test_ret_ptr by
value. Its member 'p' is PTR, not a scalar. Only scalar values, or
structs composed of scalar values, are supported as by-value kernel
function return types.
...
Suggestion:
Call a kernel function that returns only scalars by value.
A type nested deeper than the walk descends has no single member to
blame, so that case reports the depth instead:
Reason:
bpf_kfunc_call_test_ret_deep() returns STRUCT prog_test_ret_deep by
value. It nests structs more than 4 levels deep. ...
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
A global function may already return an arena pointer on its own, and check_global_ret_scalar_reg() accepts one in either half of the R0:R2 pair. Let the members of a by-value struct it returns be arena pointers as well, rather than scalars only. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
A kfunc may already return an arena pointer on its own, which the program casts back into the arena address space to use. Let the members of a by-value struct it returns be arena pointers as well, rather than scalars only. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
… type Cover the member a rejected by-value kfunc return type is blamed on. The existing case for a struct carrying a pointer now also checks that the verifier names the member, and two cases are added: a pointer inside a nested member struct, which has to be named by its path rather than by its own name, and a type nested deeper than the walk descends, which has no single member to blame and reports the depth instead. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Cover the by-value struct returns a global function may now make: two arena pointers filling R0:R2, an arena pointer beside a scalar, an array of them, and an eight byte struct returned in R0 alone. The existing cases for a struct and a union carrying a plain pointer stay rejected. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Cover the by-value struct returns a kfunc may now make: two arena pointers filling R0:R2, and an arena pointer beside a scalar. The existing cases for a struct and a nested struct carrying a plain pointer stay rejected. Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
|
Upstream branch: 48b69cc |
6ab11e5 to
6533127
Compare
Pull request for series with
subject: bpf: Allow arena pointers in by-value returns
version: 2
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1151739