bpf: Fix leak in LINK_UPDATE and enforce empty old_prog_fd
authorAndrii Nakryiko <andriin@fb.com>
Fri, 24 Apr 2020 05:20:44 +0000 (22:20 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 25 Apr 2020 00:27:02 +0000 (17:27 -0700)
Fix bug of not putting bpf_link in LINK_UPDATE command.
Also enforce zeroed old_prog_fd if no BPF_F_REPLACE flag is specified.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200424052045.4002963-1-andriin@fb.com
kernel/bpf/syscall.c

index d85f372395407df1d02ab0fe5bbd7009a2289647..bca58c235ac0c788ea37e4e965fcf112b9cb842f 100644 (file)
@@ -3628,8 +3628,10 @@ static int link_update(union bpf_attr *attr)
                return PTR_ERR(link);
 
        new_prog = bpf_prog_get(attr->link_update.new_prog_fd);
-       if (IS_ERR(new_prog))
-               return PTR_ERR(new_prog);
+       if (IS_ERR(new_prog)) {
+               ret = PTR_ERR(new_prog);
+               goto out_put_link;
+       }
 
        if (flags & BPF_F_REPLACE) {
                old_prog = bpf_prog_get(attr->link_update.old_prog_fd);
@@ -3638,6 +3640,9 @@ static int link_update(union bpf_attr *attr)
                        old_prog = NULL;
                        goto out_put_progs;
                }
+       } else if (attr->link_update.old_prog_fd) {
+               ret = -EINVAL;
+               goto out_put_progs;
        }
 
 #ifdef CONFIG_CGROUP_BPF
@@ -3653,6 +3658,8 @@ out_put_progs:
                bpf_prog_put(old_prog);
        if (ret)
                bpf_prog_put(new_prog);
+out_put_link:
+       bpf_link_put(link);
        return ret;
 }