diff mbox series

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

Message ID 20250416161756.1079178-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 16, 2025, 4:17 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

Changing the is_int_ptr to void and generic integer check and renaming
it to is_void_or_int_ptr.

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

Comments

Jiri Olsa April 17, 2025, 12:15 p.m. UTC | #1
On Thu, Apr 17, 2025 at 12:17:55AM +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
> 
> Changing the is_int_ptr to void and generic integer check and renaming
> it to is_void_or_int_ptr.
> 
> Cc: Leon Hwang <leon.hwang@linux.dev>
> Signed-off-by: KaFai Wan <kafai.wan@hotmail.com>
> ---
>  kernel/bpf/btf.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 16ba36f34dfa..0b1724453b75 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -6383,12 +6383,12 @@ struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
>  		return prog->aux->attach_btf;
>  }
>  
> -static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
> +static bool is_void_or_int_ptr(struct btf *btf, const struct btf_type *t)
>  {
>  	/* skip modifiers */
>  	t = btf_type_skip_modifiers(btf, t->type, NULL);
>  
> -	return btf_type_is_int(t);
> +	return btf_type_is_void(t) || btf_type_is_int(t);
>  }
>  
>  static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type *func_proto,
> @@ -6783,7 +6783,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
>  		 */
>  		return true;

could we remove the above check then? 

        if (t->type == 0)
                /* This is a pointer to void.
                 * It is the same as scalar from the verifier safety pov.
                 * No further pointer walking is allowed.
                 */
                return true;

jirka

>  
> -	if (is_int_ptr(btf, t))
> +	if (is_void_or_int_ptr(btf, t))
>  		return true;
>  
>  	/* this is a pointer to another type */
> -- 
> 2.43.0
>
diff mbox series

Patch

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 16ba36f34dfa..0b1724453b75 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6383,12 +6383,12 @@  struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
 		return prog->aux->attach_btf;
 }
 
-static bool is_int_ptr(struct btf *btf, const struct btf_type *t)
+static bool is_void_or_int_ptr(struct btf *btf, const struct btf_type *t)
 {
 	/* skip modifiers */
 	t = btf_type_skip_modifiers(btf, t->type, NULL);
 
-	return btf_type_is_int(t);
+	return btf_type_is_void(t) || btf_type_is_int(t);
 }
 
 static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type *func_proto,
@@ -6783,7 +6783,7 @@  bool btf_ctx_access(int off, int size, enum bpf_access_type type,
 		 */
 		return true;
 
-	if (is_int_ptr(btf, t))
+	if (is_void_or_int_ptr(btf, t))
 		return true;
 
 	/* this is a pointer to another type */