On Mon, Jun 07, 2021 at 12:42:51PM -0700, Yonghong Song wrote: SNIP > > +static int bpf_tracing_multi_attach(struct bpf_prog *prog, > + const union bpf_attr *attr) > +{ > + void __user *ubtf_ids = u64_to_user_ptr(attr->link_create.multi_btf_ids); > + u32 size, i, cnt = attr->link_create.multi_btf_ids_cnt; > + struct bpf_tracing_multi_link *link = NULL; > + struct bpf_link_primer link_primer; > + struct bpf_trampoline *tr = NULL; > + int err = -EINVAL; > + u8 nr_args = 0; > + u32 *btf_ids; > + > + if (check_multi_prog_type(prog)) > + return -EINVAL; > + > + size = cnt * sizeof(*btf_ids); > + btf_ids = kmalloc(size, GFP_USER | __GFP_NOWARN); > + if (!btf_ids) > + return -ENOMEM; > + > + err = -EFAULT; > + if (ubtf_ids && copy_from_user(btf_ids, ubtf_ids, size)) > + goto out_free; > + > + link = kzalloc(sizeof(*link), GFP_USER); > + if (!link) > + goto out_free; > + > + for (i = 0; i < cnt; i++) { > + struct bpf_attach_target_info tgt_info = {}; > + > + err = bpf_check_attach_target(NULL, prog, NULL, btf_ids[i], > + &tgt_info); > + if (err) > + goto out_free; > + > + if (ftrace_set_filter_ip(&link->ops, tgt_info.tgt_addr, 0, 0)) > + goto out_free; > + > + if (nr_args < tgt_info.fmodel.nr_args) > + nr_args = tgt_info.fmodel.nr_args; > + } > + > + tr = bpf_trampoline_multi_alloc(); > + if (!tr) > + goto out_free; > + > + bpf_func_model_nargs(&tr->func.model, nr_args); > + > + err = bpf_trampoline_link_prog(prog, tr); > + if (err) > + goto out_free; > + > + err = register_ftrace_direct_multi(&link->ops, (unsigned long) > tr->cur_image->image); > + if (err) > + goto out_free; > + > + bpf_link_init(&link->link, BPF_LINK_TYPE_TRACING_MULTI, > + &bpf_tracing_multi_link_lops, prog); > + link->attach_type = prog->expected_attach_type; > + > + err = bpf_link_prime(&link->link, &link_primer); > + if (err) > + goto out_unlink; > + > + link->tr = tr; > + /* Take extra ref so we are even with progs added by link_update. */ > + bpf_prog_inc(prog); > + return bpf_link_settle(&link_primer); > + > +out_unlink: > + unregister_ftrace_direct_multi(&link->ops); > +out_free: > + kfree(tr); > + kfree(btf_ids); > + kfree(link); > + return err; > +} > + > > Looks like cnt = 0 is okay in bpf_tracing_multi_attach(). right, we should fail for that with EINVAL, also the maximum with prog->aux->attach_btf->nr_types at least thanks, jirka