mainline inclusion from mainline-v7.4-rc1 commit 6c476d2b73056ed151c3f8b884c627c75999ed7c category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/10194 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- btf_add_type() stores the types of a BTF in btf->types[], which can hold at most BTF_MAX_TYPE entries. The types of a split BTF get IDs start_id .. start_id + nr_types - 1, so only BTF_MAX_TYPE - start_id of them fit, but neither the limit check nor the size used to grow the array accounts for start_id: the check is an equality test against BTF_MAX_TYPE ('start_id + btf->types_size == BTF_MAX_TYPE') and the new size is clamped to BTF_MAX_TYPE. The check therefore only fires if the array happens to grow to exactly BTF_MAX_TYPE - start_id entries. Otherwise, if the module has more than BTF_MAX_TYPE types, the array is filled up to BTF_MAX_TYPE entries. The next type that needs to be added reallocates the array to the same size, after which btf->types_size no longer equals btf->nr_types and the growth path is not taken anymore, so every following type is written past the end of the array: BUG: unable to handle page fault for address: ffffc90006200000 RIP: 0010:btf_add_type+0x74/0x270 Call Trace: btf_check_all_metas btf_parse_module Bound both the array size and the limit check by BTF_MAX_TYPE - start_id. Base BTF (start_id == 0) is unaffected. Fixes: 951bb64621b8 ("bpf: Add in-kernel split BTF support") Signed-off-by: Feng Yang <yangfeng@kylinos.cn> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Mahe Tardy <mahe.tardy@gmail.com> Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Link: https://patch.msgid.link/20261028031933.277550-1-yangfeng59949@163.com Signed-off-by: Pu Lehui <pulehui@huawei.com> --- kernel/bpf/btf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 1c5ed5d4b591..876f48012b1c 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -1580,15 +1580,16 @@ static int btf_add_type(struct btf_verifier_env *env, struct btf_type *t) /* Expand 'types' array */ struct btf_type **new_types; - u32 expand_by, new_size; + u32 expand_by, new_size, max_size; - if (btf->start_id + btf->types_size == BTF_MAX_TYPE) { + if (btf->start_id + btf->types_size >= BTF_MAX_TYPE) { btf_verifier_log(env, "Exceeded max num of types"); return -E2BIG; } + max_size = BTF_MAX_TYPE - btf->start_id; expand_by = max_t(u32, btf->types_size >> 2, 16); - new_size = min_t(u32, BTF_MAX_TYPE, + new_size = min_t(u32, max_size, btf->types_size + expand_by); new_types = kvcalloc(new_size, sizeof(*new_types), -- 2.34.1