On Wed, Aug 17, 2022 at 02:30:01PM -0700, Alexei Starovoitov wrote: > On Wed, Aug 17, 2022 at 11:43 AM Daniel Xu <dxu@xxxxxxxxx> wrote: > > > > +/* Check writes into `struct nf_conn` */ > > +int nf_conntrack_btf_struct_access(struct bpf_verifier_log *log, > > + const struct btf *btf, > > + const struct btf_type *t, int off, > > + int size, enum bpf_access_type atype, > > + u32 *next_btf_id, > > + enum bpf_type_flag *flag) > > +{ > > + const struct btf_type *nct = READ_ONCE(nf_conn_type); > > + s32 type_id; > > + size_t end; > > + > > + if (!nct) { > > + type_id = btf_find_by_name_kind(btf, "nf_conn", BTF_KIND_STRUCT); > > + if (type_id < 0) > > + return -EINVAL; > > + > > + nct = btf_type_by_id(btf, type_id); > > + WRITE_ONCE(nf_conn_type, nct); > > + } > > + > > + if (t != nct) { > > + bpf_log(log, "only read is supported\n"); > > + return -EACCES; > > + } > > + > > + switch (off) { > > +#if defined(CONFIG_NF_CONNTRACK_MARK) > > + case offsetof(struct nf_conn, mark): > > + end = offsetofend(struct nf_conn, mark); > > + break; > > +#endif > > + default: > > + bpf_log(log, "no write support to nf_conn at off %d\n", off); > > + return -EACCES; > > + } > > + > > + if (off + size > end) { > > + bpf_log(log, > > + "write access at off %d with size %d beyond the member of nf_conn ended at %zu\n", > > + off, size, end); > > + return -EACCES; > > + } > > + > > + return NOT_INIT; > > Took me a long time to realize that this is a copy-paste > from net/ipv4/bpf_tcp_ca.c. > It's not wrong, but misleading. > When atype == BPF_READ the return value from > btf_struct_access should only be error<0, SCALAR_VALUE, PTR_TO_BTF_ID. > For atype == BPF_WRITE we should probably standardize on > error<0, or 0. > > The NOT_INIT happens to be zero, but explicit 0 > is cleaner to avoid confusion that this is somehow enum bpf_reg_type. > > Martin, > since you've added this code in bpf_tcp_ca, wdyt? Yep, sgtm. This will be less confusing.