Skip to content

Commit d8939cb

Browse files
davemarchevskyAlexei Starovoitov
authored andcommitted
bpf: Loosen alloc obj test in verifier's reg_btf_record
btf->struct_meta_tab is populated by btf_parse_struct_metas in btf.c. There, a BTF record is created for any type containing a spin_lock or any next-gen datastructure node/head. Currently, for non-MAP_VALUE types, reg_btf_record will only search for a record using struct_meta_tab if the reg->type exactly matches (PTR_TO_BTF_ID | MEM_ALLOC). This exact match is too strict: an "allocated obj" type - returned from bpf_obj_new - might pick up other flags while working its way through the program. Loosen the check to be exact for base_type and just use MEM_ALLOC mask for type_flag. This patch is marked Fixes as the original intent of reg_btf_record was unlikely to have been to fail finding btf_record for valid alloc obj types with additional flags, some of which (e.g. PTR_UNTRUSTED) are valid register type states for alloc obj independent of this series. However, I didn't find a specific broken repro case outside of this series' added functionality, so it's possible that nothing was triggering this logic error before. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> cc: Kumar Kartikeya Dwivedi <memxor@gmail.com> Fixes: 4e814da ("bpf: Allow locking bpf_spin_lock in allocated objects") Link: https://lore.kernel.org/r/20221206231000.3180914-2-davemarchevsky@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 156ed20 commit d8939cb

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,14 +451,19 @@ static bool reg_type_not_null(enum bpf_reg_type type)
451451
type == PTR_TO_SOCK_COMMON;
452452
}
453453

454+
static bool type_is_ptr_alloc_obj(u32 type)
455+
{
456+
return base_type(type) == PTR_TO_BTF_ID && type_flag(type) & MEM_ALLOC;
457+
}
458+
454459
static struct btf_record *reg_btf_record(const struct bpf_reg_state *reg)
455460
{
456461
struct btf_record *rec = NULL;
457462
struct btf_struct_meta *meta;
458463

459464
if (reg->type == PTR_TO_MAP_VALUE) {
460465
rec = reg->map_ptr->record;
461-
} else if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC)) {
466+
} else if (type_is_ptr_alloc_obj(reg->type)) {
462467
meta = btf_find_struct_meta(reg->btf, reg->btf_id);
463468
if (meta)
464469
rec = meta->record;

0 commit comments

Comments
 (0)