On Thu, Dec 09, 2021 at 09:35:48AM -0800, Yonghong Song wrote: > BPF verifier supports direct memory access for BPF_PROG_TYPE_TRACING type > of bpf programs, e.g., a->b. If "a" is a pointer > pointing to kernel memory, bpf verifier will allow user to write > code in C like a->b and the verifier will translate it to a kernel > load properly. If "a" is a pointer to user memory, it is expected > that bpf developer should be bpf_probe_read_user() helper to > get the value a->b. Without utilizing BTF __user tagging information, > current verifier will assume that a->b is a kernel memory access > and this may generate incorrect result. The patch set looks great overall. > +/* The pointee address space encoded in BTF. */ > +enum btf_addr_space { > + BTF_ADDRSPACE_UNSPEC = 0, > + BTF_ADDRSPACE_USER = 1, > +}; > + > /* The information passed from prog-specific *_is_valid_access > * back to the verifier. > */ > @@ -473,6 +479,7 @@ struct bpf_insn_access_aux { > struct { > struct btf *btf; > u32 btf_id; > + enum btf_addr_space addr_space; > }; ... > @@ -4998,7 +4999,15 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, > > info->btf = btf; > info->btf_id = t->type; > + info->addr_space = BTF_ADDRSPACE_UNSPEC; > t = btf_type_by_id(btf, t->type); > + > + if (btf_type_is_type_tag(t)) { > + tag_value = __btf_name_by_offset(btf, t->name_off); > + if (strcmp(tag_value, "user") == 0) > + info->addr_space = BTF_ADDRSPACE_USER; > + } > + > /* skip modifiers */ > while (btf_type_is_modifier(t)) { bpf_insn_access_aux approach will work only for the first pointer deref, right? Also addr_space will consume the last 4 free bytes in bpf_reg_state. Maybe encode user/kernel as a flag into bpf_reg_type? The verifier just got extended with PTR_MAYBE_NULL and MEM_RDONLY flags. MEM_RDONLY is roughly equivalent 'const' modifier. In that sense __user attribute is similar. wdyt?