diff mbox series

[bpf-next,1/2] bpf: Allow access to const void pointer arguments in tracing programs

Message ID 20250412170626.3638516-2-kafai.wan@hotmail.com (mailing list archive)
State New
Headers show
Series bpf: Allow access to const void pointer arguments in tracing programs | expand

Commit Message

Kafai Wan April 12, 2025, 5:06 p.m. UTC
Adding support to access arguments with const void pointer arguments
in tracing programs.

Currently we allow tracing programs to access void pointers. If we try to
access argument which is pointer to const void like 2nd argument in kfree,
verifier will fail to load the program with;

0: R1=ctx() R10=fp0
; asm volatile ("r2 = *(u64 *)(r1 + 8); ");
0: (79) r2 = *(u64 *)(r1 +8)
func 'kfree' arg1 type UNKNOWN is not a struct

Adding is_void_ptr to generic void  pointer check.

Cc: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: KaFai Wan <kafai.wan@hotmail.com>
---
 kernel/bpf/btf.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Jiri Olsa April 14, 2025, 10:35 a.m. UTC | #1
On Sun, Apr 13, 2025 at 01:06:25AM +0800, KaFai Wan wrote:
> Adding support to access arguments with const void pointer arguments
> in tracing programs.
> 
> Currently we allow tracing programs to access void pointers. If we try to
> access argument which is pointer to const void like 2nd argument in kfree,
> verifier will fail to load the program with;
> 
> 0: R1=ctx() R10=fp0
> ; asm volatile ("r2 = *(u64 *)(r1 + 8); ");
> 0: (79) r2 = *(u64 *)(r1 +8)
> func 'kfree' arg1 type UNKNOWN is not a struct
> 
> Adding is_void_ptr to generic void  pointer check.
> 
> Cc: Leon Hwang <leon.hwang@linux.dev>
> Signed-off-by: KaFai Wan <kafai.wan@hotmail.com>
> ---
>  kernel/bpf/btf.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 16ba36f34dfa..e11d3afd0562 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -6383,6 +6383,14 @@ struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
>  		return prog->aux->attach_btf;
>  }
>  
> +static bool is_void_ptr(struct btf *btf, const struct btf_type *t)
> +{
> +	/* skip modifiers */
> +	t = btf_type_skip_modifiers(btf, t->type, NULL);
> +
> +	return t->type == 0;

I think you can use btf_type_is_void in here

> +}
> +
>  static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
>  {
>  	/* skip modifiers */
> @@ -6776,7 +6784,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
>  		}
>  	}
>  
> -	if (t->type == 0)
> +	if (is_void_ptr(btf, t))

lgtm,

nit, the is_void_ptr name suggest there's also ptr check in the helper function,
which is not the case. I understand it follows is_int_ptr name, but perhaps we
could rename both helpers to is_void and is_int ... feel free to ignore ;-)

jirka


>  		/* This is a pointer to void.
>  		 * It is the same as scalar from the verifier safety pov.
>  		 * No further pointer walking is allowed.
> -- 
> 2.43.0
>
Kafai Wan April 15, 2025, 2:37 p.m. UTC | #2
On Mon, Apr 14, 2025 at 6:35 PM Jiri Olsa <olsajiri@gmail.com> wrote:
>
> On Sun, Apr 13, 2025 at 01:06:25AM +0800, KaFai Wan wrote:
> > Adding support to access arguments with const void pointer arguments
> > in tracing programs.
> >
> > Currently we allow tracing programs to access void pointers. If we try to
> > access argument which is pointer to const void like 2nd argument in kfree,
> > verifier will fail to load the program with;
> >
> > 0: R1=ctx() R10=fp0
> > ; asm volatile ("r2 = *(u64 *)(r1 + 8); ");
> > 0: (79) r2 = *(u64 *)(r1 +8)
> > func 'kfree' arg1 type UNKNOWN is not a struct
> >
> > Adding is_void_ptr to generic void  pointer check.
> >
> > Cc: Leon Hwang <leon.hwang@linux.dev>
> > Signed-off-by: KaFai Wan <kafai.wan@hotmail.com>
> > ---
> >  kernel/bpf/btf.c | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> > index 16ba36f34dfa..e11d3afd0562 100644
> > --- a/kernel/bpf/btf.c
> > +++ b/kernel/bpf/btf.c
> > @@ -6383,6 +6383,14 @@ struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
> >               return prog->aux->attach_btf;
> >  }
> >
> > +static bool is_void_ptr(struct btf *btf, const struct btf_type *t)
> > +{
> > +     /* skip modifiers */
> > +     t = btf_type_skip_modifiers(btf, t->type, NULL);
> > +
> > +     return t->type == 0;
>
> I think you can use btf_type_is_void in here
>

Yes, I will use btf_type_is_void.

> > +}
> > +
> >  static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
> >  {
> >       /* skip modifiers */
> > @@ -6776,7 +6784,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
> >               }
> >       }
> >
> > -     if (t->type == 0)
> > +     if (is_void_ptr(btf, t))
>
> lgtm,
>
> nit, the is_void_ptr name suggest there's also ptr check in the helper function,
> which is not the case. I understand it follows is_int_ptr name, but perhaps we
> could rename both helpers to is_void and is_int ... feel free to ignore ;-)

you are right, I will rename it. but I'm not sure if it's possible to merge
these two functions into one like is_void_or_int, they both skip modifiers.

>
> jirka
>
>
> >               /* This is a pointer to void.
> >                * It is the same as scalar from the verifier safety pov.
> >                * No further pointer walking is allowed.
> > --
> > 2.43.0
> >

thanks,
kafai
diff mbox series

Patch

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 16ba36f34dfa..e11d3afd0562 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6383,6 +6383,14 @@  struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
 		return prog->aux->attach_btf;
 }
 
+static bool is_void_ptr(struct btf *btf, const struct btf_type *t)
+{
+	/* skip modifiers */
+	t = btf_type_skip_modifiers(btf, t->type, NULL);
+
+	return t->type == 0;
+}
+
 static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
 {
 	/* skip modifiers */
@@ -6776,7 +6784,7 @@  bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 		}
 	}
 
-	if (t->type == 0)
+	if (is_void_ptr(btf, t))
 		/* This is a pointer to void.
 		 * It is the same as scalar from the verifier safety pov.
 		 * No further pointer walking is allowed.