On Fri, Jul 22, 2022 at 6:16 PM Alexei Starovoitov alexei.starovoitov@gmail.com wrote:
On Fri, Jul 22, 2022 at 1:46 AM Benjamin Tissoires benjamin.tissoires@redhat.com wrote:
When a kfunc was trying to access data from context in a syscall eBPF program, the verifier was rejecting the call. This is because the syscall context is not known at compile time, and so we need to check this when actually accessing it.
Check for the valid memory access and allow such situation to happen.
Acked-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Benjamin Tissoires benjamin.tissoires@redhat.com
changes in v8:
- fixup comment
- return -EACCESS instead of -EINVAL for consistency
changes in v7:
- renamed access_t into atype
- allow zero-byte read
- check_mem_access() to the correct offset/size
new in v6
kernel/bpf/verifier.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7c1e056624f9..c807c5d7085a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -248,6 +248,7 @@ struct bpf_call_arg_meta { struct bpf_map *map_ptr; bool raw_mode; bool pkt_access;
bool is_kfunc; u8 release_regno; int regno; int access_size;
@@ -5170,6 +5171,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno, struct bpf_call_arg_meta *meta) { struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
enum bpf_prog_type prog_type = resolve_prog_type(env->prog); u32 *max_access; switch (base_type(reg->type)) {
@@ -5223,6 +5225,24 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno, env, regno, reg->off, access_size, zero_size_allowed, ACCESS_HELPER, meta);
case PTR_TO_CTX:
/* in case of a kfunc called in a program of type SYSCALL, the context is
* user supplied, so not computed statically.
* Dynamically check it now
*/
if (prog_type == BPF_PROG_TYPE_SYSCALL && meta && meta->is_kfunc) {
prog_type check looks a bit odd here. Can we generalize with if (!env->ops->convert_ctx_access
Yep, seems to be working fine for my use case and the test cases I have in this series.
In other words any program type that doesn't have ctx rewrites can use helpers to access ctx fields ?
Also why kfunc only? It looks safe to allow normal helpers as well.
Well, not sure what is happening here, but if I remove the check for kfunc, the test for PTR_TO_CTX == NULL and size == 0 gives me a -EINVAL.
The original reason for kfunc only was because I wanted to scope the changes to something I can control, but now I am completely out of ideas on why the NULL test fails if it enters the if branch.
Unfortunately I won't have a lot of time this week to tackle this (I am on holiday with my family), and next will be tough too (at home but doing renovations).
I can send the fixup to remove the prog_type check as I just made sure it works with the selftests. But I won't be able to dig further why it fails without the kfunc check, because not enough time and concentration.
Cheers, Benjamin