Merge tag 'smp-urgent-2023-09-02' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / kernel / bpf / syscall.c
index cb65854..ebeb069 100644 (file)
@@ -657,7 +657,6 @@ void bpf_obj_free_fields(const struct btf_record *rec, void *obj)
                        if (!btf_is_kernel(field->kptr.btf)) {
                                pointee_struct_meta = btf_find_struct_meta(field->kptr.btf,
                                                                           field->kptr.btf_id);
-                               WARN_ON_ONCE(!pointee_struct_meta);
                                migrate_disable();
                                __bpf_obj_drop_impl(xchgd_field, pointee_struct_meta ?
                                                                 pointee_struct_meta->record :
@@ -2815,10 +2814,12 @@ static void bpf_link_free_id(int id)
 
 /* Clean up bpf_link and corresponding anon_inode file and FD. After
  * anon_inode is created, bpf_link can't be just kfree()'d due to deferred
- * anon_inode's release() call. This helper marksbpf_link as
+ * anon_inode's release() call. This helper marks bpf_link as
  * defunct, releases anon_inode file and puts reserved FD. bpf_prog's refcnt
  * is not decremented, it's the responsibility of a calling code that failed
  * to complete bpf_link initialization.
+ * This helper eventually calls link's dealloc callback, but does not call
+ * link's release callback.
  */
 void bpf_link_cleanup(struct bpf_link_primer *primer)
 {
@@ -3655,34 +3656,6 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
        return fd;
 }
 
-static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
-                                            enum bpf_attach_type attach_type)
-{
-       switch (prog->type) {
-       case BPF_PROG_TYPE_CGROUP_SOCK:
-       case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
-       case BPF_PROG_TYPE_CGROUP_SOCKOPT:
-       case BPF_PROG_TYPE_SK_LOOKUP:
-               return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
-       case BPF_PROG_TYPE_CGROUP_SKB:
-               if (!capable(CAP_NET_ADMIN))
-                       /* cg-skb progs can be loaded by unpriv user.
-                        * check permissions at attach time.
-                        */
-                       return -EPERM;
-               return prog->enforce_expected_attach_type &&
-                       prog->expected_attach_type != attach_type ?
-                       -EINVAL : 0;
-       case BPF_PROG_TYPE_KPROBE:
-               if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
-                   attach_type != BPF_TRACE_KPROBE_MULTI)
-                       return -EINVAL;
-               return 0;
-       default:
-               return 0;
-       }
-}
-
 static enum bpf_prog_type
 attach_type_to_prog_type(enum bpf_attach_type attach_type)
 {
@@ -3749,6 +3722,62 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
        }
 }
 
+static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
+                                            enum bpf_attach_type attach_type)
+{
+       enum bpf_prog_type ptype;
+
+       switch (prog->type) {
+       case BPF_PROG_TYPE_CGROUP_SOCK:
+       case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
+       case BPF_PROG_TYPE_CGROUP_SOCKOPT:
+       case BPF_PROG_TYPE_SK_LOOKUP:
+               return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
+       case BPF_PROG_TYPE_CGROUP_SKB:
+               if (!capable(CAP_NET_ADMIN))
+                       /* cg-skb progs can be loaded by unpriv user.
+                        * check permissions at attach time.
+                        */
+                       return -EPERM;
+               return prog->enforce_expected_attach_type &&
+                       prog->expected_attach_type != attach_type ?
+                       -EINVAL : 0;
+       case BPF_PROG_TYPE_EXT:
+               return 0;
+       case BPF_PROG_TYPE_NETFILTER:
+               if (attach_type != BPF_NETFILTER)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_PERF_EVENT:
+       case BPF_PROG_TYPE_TRACEPOINT:
+               if (attach_type != BPF_PERF_EVENT)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_KPROBE:
+               if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
+                   attach_type != BPF_TRACE_KPROBE_MULTI)
+                       return -EINVAL;
+               if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI &&
+                   attach_type != BPF_TRACE_UPROBE_MULTI)
+                       return -EINVAL;
+               if (attach_type != BPF_PERF_EVENT &&
+                   attach_type != BPF_TRACE_KPROBE_MULTI &&
+                   attach_type != BPF_TRACE_UPROBE_MULTI)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_SCHED_CLS:
+               if (attach_type != BPF_TCX_INGRESS &&
+                   attach_type != BPF_TCX_EGRESS)
+                       return -EINVAL;
+               return 0;
+       default:
+               ptype = attach_type_to_prog_type(attach_type);
+               if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type)
+                       return -EINVAL;
+               return 0;
+       }
+}
+
 #define BPF_PROG_ATTACH_LAST_FIELD expected_revision
 
 #define BPF_F_ATTACH_MASK_BASE \
@@ -4852,10 +4881,9 @@ err_put:
        return err;
 }
 
-#define BPF_LINK_CREATE_LAST_FIELD link_create.kprobe_multi.cookies
+#define BPF_LINK_CREATE_LAST_FIELD link_create.uprobe_multi.pid
 static int link_create(union bpf_attr *attr, bpfptr_t uattr)
 {
-       enum bpf_prog_type ptype;
        struct bpf_prog *prog;
        int ret;
 
@@ -4874,45 +4902,6 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
        if (ret)
                goto out;
 
-       switch (prog->type) {
-       case BPF_PROG_TYPE_EXT:
-               break;
-       case BPF_PROG_TYPE_NETFILTER:
-               if (attr->link_create.attach_type != BPF_NETFILTER) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_PERF_EVENT:
-       case BPF_PROG_TYPE_TRACEPOINT:
-               if (attr->link_create.attach_type != BPF_PERF_EVENT) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_KPROBE:
-               if (attr->link_create.attach_type != BPF_PERF_EVENT &&
-                   attr->link_create.attach_type != BPF_TRACE_KPROBE_MULTI) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_SCHED_CLS:
-               if (attr->link_create.attach_type != BPF_TCX_INGRESS &&
-                   attr->link_create.attach_type != BPF_TCX_EGRESS) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       default:
-               ptype = attach_type_to_prog_type(attr->link_create.attach_type);
-               if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       }
-
        switch (prog->type) {
        case BPF_PROG_TYPE_CGROUP_SKB:
        case BPF_PROG_TYPE_CGROUP_SOCK:
@@ -4969,8 +4958,10 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
        case BPF_PROG_TYPE_KPROBE:
                if (attr->link_create.attach_type == BPF_PERF_EVENT)
                        ret = bpf_perf_link_attach(attr, prog);
-               else
+               else if (attr->link_create.attach_type == BPF_TRACE_KPROBE_MULTI)
                        ret = bpf_kprobe_multi_link_attach(attr, prog);
+               else if (attr->link_create.attach_type == BPF_TRACE_UPROBE_MULTI)
+                       ret = bpf_uprobe_multi_link_attach(attr, prog);
                break;
        default:
                ret = -EINVAL;