Re: [bug report] bpf: Add fd-based tcx multi-prog infra with link support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dan,

On 1/23/24 11:43 AM, Dan Carpenter wrote:
Hello Daniel Borkmann and Benjamin Tissoires,

I've included both warnings because they're sort of related and
hopefully it will save time to have this discussion in one thread.  I
recently added fdget() to my Smatch check for CVE-2023-1838 type
warnings and it generated the following output.  I'm not an expert on
this stuff, I'm just a monkey see, monkey do programmer.  I've filtered
out the obvious false positives but I'm not sure about these.

The patch e420bed02507: "bpf: Add fd-based tcx multi-prog infra with
link support" from Jul 19, 2023 and f5c27da4e3c8 ("HID: initial BPF
implementation") from Nov 3, 2022 introduce the following static
checker warnings:

drivers/hid/bpf/hid_bpf_dispatch.c:287 hid_bpf_attach_prog() warn: double fget(): 'prog_fd'
drivers/hid/bpf/hid_bpf_jmp_table.c:427 __hid_bpf_attach_prog() warn: fd re-used after fget(): 'prog_fd'
kernel/bpf/syscall.c:3985 bpf_prog_detach() warn: double fget(): 'attr->attach_bpf_fd'
kernel/bpf/syscall.c:3988 bpf_prog_detach() warn: double fget(): 'attr->attach_bpf_fd'
kernel/bpf/syscall.c:3991 bpf_prog_detach() warn: double fget(): 'attr->attach_bpf_fd'
kernel/bpf/syscall.c:4001 bpf_prog_detach() warn: double fget(): 'attr->attach_bpf_fd'


[...]
kernel/bpf/syscall.c
     3956 static int bpf_prog_detach(const union bpf_attr *attr)
     3957 {
     3958         struct bpf_prog *prog = NULL;
     3959         enum bpf_prog_type ptype;
     3960         int ret;
     3961
     3962         if (CHECK_ATTR(BPF_PROG_DETACH))
     3963                 return -EINVAL;
     3964
     3965         ptype = attach_type_to_prog_type(attr->attach_type);
     3966         if (bpf_mprog_supported(ptype)) {
     3967                 if (ptype == BPF_PROG_TYPE_UNSPEC)
     3968                         return -EINVAL;
     3969                 if (attr->attach_flags & ~BPF_F_ATTACH_MASK_MPROG)
     3970                         return -EINVAL;
     3971                 if (attr->attach_bpf_fd) {
     3972                         prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
                                                           ^^^^^^^^^^^^^^^^^^^
 From my understanding then this prog might not be the same prog which
we detach from later...

Thanks for double checking, Dan! This branch above is only accessible when
bpf_mprog_supported(ptype) holds true which is as of today BPF_PROG_TYPE_SCHED_CLS.

     3973                         if (IS_ERR(prog))
     3974                                 return PTR_ERR(prog);
     3975                 }
     3976         } else if (attr->attach_flags ||
     3977                    attr->relative_fd ||
     3978                    attr->expected_revision) {
     3979                 return -EINVAL;
     3980         }
     3981
     3982         switch (ptype) {
     3983         case BPF_PROG_TYPE_SK_MSG:
     3984         case BPF_PROG_TYPE_SK_SKB:
--> 3985                 ret = sock_map_prog_detach(attr, ptype);
                                                     ^^^^
here.  Because instead of re-using prog we look it up again.

So we never enter into this switch case given the ptype.

     3986                 break;
     3987         case BPF_PROG_TYPE_LIRC_MODE2:
     3988                 ret = lirc_prog_detach(attr);
     3989                 break;
     3990         case BPF_PROG_TYPE_FLOW_DISSECTOR:
     3991                 ret = netns_bpf_prog_detach(attr, ptype);
     3992                 break;
     3993         case BPF_PROG_TYPE_CGROUP_DEVICE:
     3994         case BPF_PROG_TYPE_CGROUP_SKB:
     3995         case BPF_PROG_TYPE_CGROUP_SOCK:
     3996         case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
     3997         case BPF_PROG_TYPE_CGROUP_SOCKOPT:
     3998         case BPF_PROG_TYPE_CGROUP_SYSCTL:
     3999         case BPF_PROG_TYPE_SOCK_OPS:
     4000         case BPF_PROG_TYPE_LSM:
     4001                 ret = cgroup_bpf_prog_detach(attr, ptype);
     4002                 break;
     4003         case BPF_PROG_TYPE_SCHED_CLS:
     4004                 if (attr->attach_type == BPF_TCX_INGRESS ||
     4005                     attr->attach_type == BPF_TCX_EGRESS)
     4006                         ret = tcx_prog_detach(attr, prog);
     4007                 else
     4008                         ret = netkit_prog_detach(attr, prog);

... only these two detach functions above.

     4009                 break;
     4010         default:
     4011                 ret = -EINVAL;
     4012         }
     4013
     4014         if (prog)
     4015                 bpf_prog_put(prog);
     4016         return ret;
     4017 }

Thanks,
Daniel




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux