On Tue, Aug 17, 2021 at 10:36 AM Colin Ian King <colin.king@xxxxxxxxxxxxx> wrote: > > Hi, > > Static analysis with Coverity on linux-next has detected a potential > issue with the following commit: > > commit b89fbfbb854c9afc3047e8273cc3a694650b802e > Author: Andrii Nakryiko <andrii@xxxxxxxxxx> > Date: Sun Aug 15 00:05:57 2021 -0700 > > bpf: Implement minimal BPF perf link > > The analysis is as follows: > > 2936 static int bpf_perf_link_attach(const union bpf_attr *attr, struct > bpf_prog *prog) > 2937 { > > 1. var_decl: Declaring variable link_primer without initializer. > > 2938 struct bpf_link_primer link_primer; > 2939 struct bpf_perf_link *link; > 2940 struct perf_event *event; > 2941 struct file *perf_file; > 2942 int err; > 2943 > > 2. Condition attr->link_create.flags, taking false branch. > > 2944 if (attr->link_create.flags) > 2945 return -EINVAL; > 2946 > 2947 perf_file = perf_event_get(attr->link_create.target_fd); > > 3. Condition IS_ERR(perf_file), taking false branch. > > 2948 if (IS_ERR(perf_file)) > 2949 return PTR_ERR(perf_file); > 2950 > 2951 link = kzalloc(sizeof(*link), GFP_USER); > > 4. Condition !link, taking false branch. > > 2952 if (!link) { > 2953 err = -ENOMEM; > 2954 goto out_put_file; > 2955 } > 2956 bpf_link_init(&link->link, BPF_LINK_TYPE_PERF_EVENT, > &bpf_perf_link_lops, prog); > 2957 link->perf_file = perf_file; > 2958 > 2959 err = bpf_link_prime(&link->link, &link_primer); > > 5. Condition err, taking false branch. > > 2960 if (err) { > 2961 kfree(link); > 2962 goto out_put_file; > 2963 } > 2964 > 2965 event = perf_file->private_data; > 2966 err = perf_event_set_bpf_prog(event, prog, > attr->link_create.perf_event.bpf_cookie); > > 6. Condition err, taking true branch. > 2967 if (err) { > 7. uninit_use_in_call: Using uninitialized value link_primer.fd when > calling bpf_link_cleanup. > 8. uninit_use_in_call: Using uninitialized value link_primer.file > when calling bpf_link_cleanup. > 9. uninit_use_in_call: Using uninitialized value link_primer.id when > calling bpf_link_cleanup. > > Uninitialized pointer read (UNINIT) > 10. uninit_use_in_call: Using uninitialized value link_primer.link > when calling bpf_link_cleanup. > > 2968 bpf_link_cleanup(&link_primer); > 2969 goto out_put_file; > 2970 } > 2971 /* perf_event_set_bpf_prog() doesn't take its own refcnt on > prog */ > 2972 bpf_prog_inc(prog); > > I'm not 100% sure if these are false-positives, but I thought I should > report the issues as potentially there is a pointer access on an > uninitialized pointer on line 2968. Look at bpf_link_prime() implementation. If it succeeds, link_primer is fully initialized. We use this pattern in many places, this is the first time someone reports any potential issues with it. It's a bit strange that Coverity doesn't recognize such a typical output parameter initialization pattern, tbh. Maybe the global nature of bpf_link_prime() throws it off (it assumes it can be "overridden" during linking?) But I double-checked everything twice, all seems to be good. Zero-initializing link_primer would be a total waste. > > Colin