diff mbox series

[bpf,1/2] bpf: Fix calling global functions from BPF_PROG_TYPE_EXT programs

Message ID 20220603154028.24904-1-toke@redhat.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series [bpf,1/2] bpf: Fix calling global functions from BPF_PROG_TYPE_EXT programs | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf, async
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 10 this patch: 10
netdev/cc_maintainers success CCed 11 of 11 maintainers
netdev/build_clang success Errors and warnings before: 7 this patch: 7
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 10 this patch: 10
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 24 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-VM_Test-1 success Logs for Kernel LATEST on ubuntu-latest with gcc
bpf/vmtest-bpf-VM_Test-2 success Logs for Kernel LATEST on ubuntu-latest with llvm-15
bpf/vmtest-bpf-PR fail PR summary
bpf/vmtest-bpf-VM_Test-3 fail Logs for Kernel LATEST on z15 with gcc

Commit Message

Toke Høiland-Jørgensen June 3, 2022, 3:40 p.m. UTC
The verifier allows programs to call global functions as long as their
argument types match, using BTF to check the function arguments. One of the
allowed argument types to such global functions is PTR_TO_CTX; however the
check for this fails on BPF_PROG_TYPE_EXT functions because the verifier
uses the wrong type to fetch the vmlinux BTF ID for the program context
type. This failure is seen when an XDP program is loaded using
libxdp (which loads it as BPF_PROG_TYPE_EXT and attaches it to a global XDP
type program).

Fix the issue by passing in the target program type instead of the
BPF_PROG_TYPE_EXT type to bpf_prog_get_ctx() when checking function
argument compatibility.

The first Fixes tag refers to the latest commit that touched the code in
question, while the second one points to the code that first introduced
the global function call verification.

Fixes: 3363bd0cfbb8 ("bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support")
Fixes: 51c39bb1d5d1 ("bpf: Introduce function-by-function verification")
Reported-by: Simon Sundberg <simon.sundberg@kau.se>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 kernel/bpf/btf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Kumar Kartikeya Dwivedi June 3, 2022, 5:34 p.m. UTC | #1
On Fri, Jun 03, 2022 at 09:10:26PM IST, Toke Høiland-Jørgensen wrote:
> The verifier allows programs to call global functions as long as their
> argument types match, using BTF to check the function arguments. One of the
> allowed argument types to such global functions is PTR_TO_CTX; however the
> check for this fails on BPF_PROG_TYPE_EXT functions because the verifier
> uses the wrong type to fetch the vmlinux BTF ID for the program context
> type. This failure is seen when an XDP program is loaded using
> libxdp (which loads it as BPF_PROG_TYPE_EXT and attaches it to a global XDP
> type program).
>
> Fix the issue by passing in the target program type instead of the
> BPF_PROG_TYPE_EXT type to bpf_prog_get_ctx() when checking function
> argument compatibility.
>
> The first Fixes tag refers to the latest commit that touched the code in
> question, while the second one points to the code that first introduced
> the global function call verification.
>
> Fixes: 3363bd0cfbb8 ("bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support")
> Fixes: 51c39bb1d5d1 ("bpf: Introduce function-by-function verification")
> Reported-by: Simon Sundberg <simon.sundberg@kau.se>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> ---
>  kernel/bpf/btf.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 7bccaa4646e5..361de7304c4d 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -6054,6 +6054,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
>  				    struct bpf_reg_state *regs,
>  				    bool ptr_to_mem_ok)
>  {
> +	enum bpf_prog_type prog_type = env->prog->type;
>  	struct bpf_verifier_log *log = &env->log;
>  	u32 i, nargs, ref_id, ref_obj_id = 0;
>  	bool is_kfunc = btf_is_kernel(btf);
> @@ -6095,6 +6096,9 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
>  						     BTF_KFUNC_TYPE_KPTR_ACQUIRE, func_id);
>  	}
>
> +	if (prog_type == BPF_PROG_TYPE_EXT && env->prog->aux->dst_prog)
> +		prog_type = env->prog->aux->dst_prog->type;
> +

nit: it might be better to reuse resolve_prog_type here.

>  	/* check that BTF function arguments match actual types that the
>  	 * verifier sees.
>  	 */
> @@ -6171,7 +6175,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
>  				return -EINVAL;
>  			}
>  			/* rest of the arguments can be anything, like normal kfunc */
> -		} else if (btf_get_prog_ctx_type(log, btf, t, env->prog->type, i)) {
> +		} else if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
>  			/* If function expects ctx type in BTF check that caller
>  			 * is passing PTR_TO_CTX.
>  			 */
> --
> 2.36.1
>

--
Kartikeya
diff mbox series

Patch

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 7bccaa4646e5..361de7304c4d 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6054,6 +6054,7 @@  static int btf_check_func_arg_match(struct bpf_verifier_env *env,
 				    struct bpf_reg_state *regs,
 				    bool ptr_to_mem_ok)
 {
+	enum bpf_prog_type prog_type = env->prog->type;
 	struct bpf_verifier_log *log = &env->log;
 	u32 i, nargs, ref_id, ref_obj_id = 0;
 	bool is_kfunc = btf_is_kernel(btf);
@@ -6095,6 +6096,9 @@  static int btf_check_func_arg_match(struct bpf_verifier_env *env,
 						     BTF_KFUNC_TYPE_KPTR_ACQUIRE, func_id);
 	}
 
+	if (prog_type == BPF_PROG_TYPE_EXT && env->prog->aux->dst_prog)
+		prog_type = env->prog->aux->dst_prog->type;
+
 	/* check that BTF function arguments match actual types that the
 	 * verifier sees.
 	 */
@@ -6171,7 +6175,7 @@  static int btf_check_func_arg_match(struct bpf_verifier_env *env,
 				return -EINVAL;
 			}
 			/* rest of the arguments can be anything, like normal kfunc */
-		} else if (btf_get_prog_ctx_type(log, btf, t, env->prog->type, i)) {
+		} else if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
 			/* If function expects ctx type in BTF check that caller
 			 * is passing PTR_TO_CTX.
 			 */