Re: [PATCH bpf-next v4 06/10] bpf: Track provenance for pointers formed from referenced PTR_TO_BTF_ID
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Date: 2021-12-19 05:25:45
Also in:
bpf, netfilter-devel
On Sun, Dec 19, 2021 at 10:35:18AM IST, Alexei Starovoitov wrote:
On Sat, Dec 18, 2021 at 8:33 PM Kumar Kartikeya Dwivedi [off-list ref] wrote:quoted
It is, but into parent_ref_obj_id, to match during release_reference.quoted
Shouldn't r2 get a different ref_obj_id after r2 = r1->next ?It's ref_obj_id is still 0. Thinking about this more, we actually only need 1 extra bit of information in reg_state, not even a new member. We can simply copy ref_obj_id and set this bit, then we can reject this register during release but consider it during release_reference.It seems to me that this patch created the problem and it's trying to fix it at the same time.
Yes, sort of. Maybe I need to improve the commit message? I give an example below, and the first half of commit explains that if we simply did copy ref_obj_id, it would lead to the case in the previous mail (same BTF ID ptr can be passed), so we need to do something different. Maybe that is what is confusing you.
mark_btf_ld_reg() shouldn't be copying ref_obj_id. If it keeps it as zero the problem will not happen, no?
It is copying it but writing it to parent_ref_obj_id. It keeps ref_obj_id as 0 for all deref pointers. r1 = acq(); // r1.ref = acquire_reference_state(); ref = N r2 = r1->a; // mark_btf_ld_reg -> copy r1.(ref ?: parent_ref) -> so r2.parent_ref = r1.ref r3 = r2->b; // mark_btf_ld_reg -> copy r2.(ref ?: parent_ref) -> so r3.parent_ref = r2.parent_ref r4 = r3->c; // mark_btf_ld_reg -> copy r3.(ref ?: parent_ref) -> so r4.parent_ref = r3.parent_ref rel(r1); // if (reg.ref == r1.ref || reg.parent_ref == r1.ref) invalidate(reg) As you see, mark_btf_ld_reg only ever writes to parent_ref_obj_id, not ref_obj_id. It just copies ref_obj_id when it is set, over parent_ref_obj_id, and only one of two can be set. -- Kartikeya