[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 3c4807322660d4290ac9062c034aed6b87243861
WARNING: Author mismatch between patch and upstream commit: Backport author: Puranjay Mohanpuranjay@kernel.org Commit author: Hao Luohaoluo@google.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.14.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (different SHA1: 3c141c82b958)
Note: The patch differs from the upstream commit: --- 1: 3c4807322660d ! 1: 687af1d867c44 bpf: Replace RET_XXX_OR_NULL with RET_XXX | PTR_MAYBE_NULL @@ Metadata ## Commit message ## bpf: Replace RET_XXX_OR_NULL with RET_XXX | PTR_MAYBE_NULL
+ commit 3c4807322660d4290ac9062c034aed6b87243861 upstream. + We have introduced a new type to make bpf_ret composable, by reserving high bits to represent flags.
@@ Commit message
Signed-off-by: Hao Luo haoluo@google.com Signed-off-by: Alexei Starovoitov ast@kernel.org + Signed-off-by: Puranjay Mohan puranjay@kernel.org Link: https://lore.kernel.org/bpf/20211217003152.48334-4-haoluo@google.com + Cc: stable@vger.kernel.org # 5.10.x
## include/linux/bpf.h ## @@ include/linux/bpf.h: enum bpf_return_type { @@ include/linux/bpf.h: enum bpf_return_type { + RET_PTR_TO_SOCK_COMMON, /* returns a pointer to a sock_common */ + RET_PTR_TO_ALLOC_MEM, /* returns a pointer to dynamically allocated memory */ RET_PTR_TO_MEM_OR_BTF_ID, /* returns a pointer to a valid memory or a btf_id */ - RET_PTR_TO_BTF_ID, /* returns a pointer to a btf_id */ ++ RET_PTR_TO_BTF_ID, /* returns a pointer to a btf_id */ __BPF_RET_TYPE_MAX,
+ /* Extended ret_types. */ @@ kernel/bpf/helpers.c: BPF_CALL_2(bpf_per_cpu_ptr, const void *, ptr, u32, cpu) };
## kernel/bpf/verifier.c ## -@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn - int *insn_idx_p) +@@ kernel/bpf/verifier.c: static int check_reference_leak(struct bpf_verifier_env *env) + static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn_idx) { const struct bpf_func_proto *fn = NULL; + enum bpf_return_type ret_type; struct bpf_reg_state *regs; struct bpf_call_arg_meta meta; - int insn_idx = *insn_idx_p; -@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + bool changes_data; +@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn regs[BPF_REG_0].subreg_def = DEF_NOT_SUBREG;
/* update return register (already marked as written above) */ @@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env /* There is no offset yet applied, variable or fixed */ mark_reg_known_zero(env, regs, BPF_REG_0); /* remember map_ptr, so that check_map_access() -@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn +@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn + return -EINVAL; } regs[BPF_REG_0].map_ptr = meta.map_ptr; - regs[BPF_REG_0].map_uid = meta.map_uid; - if (fn->ret_type == RET_PTR_TO_MAP_VALUE) { + if (type_may_be_null(ret_type)) { + regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; @@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env const struct btf_type *t;
mark_reg_known_zero(env, regs, BPF_REG_0); -@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn +@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn return -EINVAL; } regs[BPF_REG_0].type = @@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env - PTR_TO_BTF_ID : PTR_TO_BTF_ID_OR_NULL; + (ret_type & PTR_MAYBE_NULL) ? + PTR_TO_BTF_ID_OR_NULL : PTR_TO_BTF_ID; - regs[BPF_REG_0].btf = meta.ret_btf; regs[BPF_REG_0].btf_id = meta.ret_btf_id; } -- } else if (fn->ret_type == RET_PTR_TO_BTF_ID_OR_NULL || -- fn->ret_type == RET_PTR_TO_BTF_ID) { +- } else if (fn->ret_type == RET_PTR_TO_BTF_ID_OR_NULL) { + } else if (base_type(ret_type) == RET_PTR_TO_BTF_ID) { int ret_btf_id;
mark_reg_known_zero(env, regs, BPF_REG_0); -- regs[BPF_REG_0].type = fn->ret_type == RET_PTR_TO_BTF_ID ? -- PTR_TO_BTF_ID : -- PTR_TO_BTF_ID_OR_NULL; +- regs[BPF_REG_0].type = PTR_TO_BTF_ID_OR_NULL; + regs[BPF_REG_0].type = (ret_type & PTR_MAYBE_NULL) ? -+ PTR_TO_BTF_ID_OR_NULL : -+ PTR_TO_BTF_ID; ++ PTR_TO_BTF_ID_OR_NULL : ++ PTR_TO_BTF_ID; ret_btf_id = *fn->ret_btf_id; if (ret_btf_id == 0) { - verbose(env, "invalid return type %d of func %s#%d\n", @@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env + func_id); return -EINVAL; } - /* current BPF helper definitions are only coming from -@@ kernel/bpf/verifier.c: static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn - regs[BPF_REG_0].btf = btf_vmlinux; regs[BPF_REG_0].btf_id = ret_btf_id; } else { - verbose(env, "unknown return type %d of func %s#%d\n", ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |