mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
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: 4e814da0d5
("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>
This commit is contained in:
parent
156ed20d22
commit
d8939cb0a0
@ -451,6 +451,11 @@ static bool reg_type_not_null(enum bpf_reg_type type)
|
||||
type == PTR_TO_SOCK_COMMON;
|
||||
}
|
||||
|
||||
static bool type_is_ptr_alloc_obj(u32 type)
|
||||
{
|
||||
return base_type(type) == PTR_TO_BTF_ID && type_flag(type) & MEM_ALLOC;
|
||||
}
|
||||
|
||||
static struct btf_record *reg_btf_record(const struct bpf_reg_state *reg)
|
||||
{
|
||||
struct btf_record *rec = NULL;
|
||||
@ -458,7 +463,7 @@ static struct btf_record *reg_btf_record(const struct bpf_reg_state *reg)
|
||||
|
||||
if (reg->type == PTR_TO_MAP_VALUE) {
|
||||
rec = reg->map_ptr->record;
|
||||
} else if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC)) {
|
||||
} else if (type_is_ptr_alloc_obj(reg->type)) {
|
||||
meta = btf_find_struct_meta(reg->btf, reg->btf_id);
|
||||
if (meta)
|
||||
rec = meta->record;
|
||||
|
Loading…
Reference in New Issue
Block a user