OSDN Git Service

bpf: Attach raw_tp program with BTF via type name
authorAlexei Starovoitov <ast@kernel.org>
Wed, 16 Oct 2019 03:25:01 +0000 (20:25 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 17 Oct 2019 14:44:35 +0000 (16:44 +0200)
BTF type id specified at program load time has all
necessary information to attach that program to raw tracepoint.
Use kernel type name to find raw tracepoint.

Add missing CHECK_ATTR() condition.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20191016032505.2089704-8-ast@kernel.org
kernel/bpf/syscall.c

index b56c482..523e3ac 100644 (file)
@@ -1816,17 +1816,52 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
        struct bpf_raw_tracepoint *raw_tp;
        struct bpf_raw_event_map *btp;
        struct bpf_prog *prog;
-       char tp_name[128];
+       const char *tp_name;
+       char buf[128];
        int tp_fd, err;
 
-       if (strncpy_from_user(tp_name, u64_to_user_ptr(attr->raw_tracepoint.name),
-                             sizeof(tp_name) - 1) < 0)
-               return -EFAULT;
-       tp_name[sizeof(tp_name) - 1] = 0;
+       if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN))
+               return -EINVAL;
+
+       prog = bpf_prog_get(attr->raw_tracepoint.prog_fd);
+       if (IS_ERR(prog))
+               return PTR_ERR(prog);
+
+       if (prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT &&
+           prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE) {
+               err = -EINVAL;
+               goto out_put_prog;
+       }
+
+       if (prog->type == BPF_PROG_TYPE_RAW_TRACEPOINT &&
+           prog->aux->attach_btf_id) {
+               if (attr->raw_tracepoint.name) {
+                       /* raw_tp name should not be specified in raw_tp
+                        * programs that were verified via in-kernel BTF info
+                        */
+                       err = -EINVAL;
+                       goto out_put_prog;
+               }
+               /* raw_tp name is taken from type name instead */
+               tp_name = kernel_type_name(prog->aux->attach_btf_id);
+               /* skip the prefix */
+               tp_name += sizeof("btf_trace_") - 1;
+       } else {
+               if (strncpy_from_user(buf,
+                                     u64_to_user_ptr(attr->raw_tracepoint.name),
+                                     sizeof(buf) - 1) < 0) {
+                       err = -EFAULT;
+                       goto out_put_prog;
+               }
+               buf[sizeof(buf) - 1] = 0;
+               tp_name = buf;
+       }
 
        btp = bpf_get_raw_tracepoint(tp_name);
-       if (!btp)
-               return -ENOENT;
+       if (!btp) {
+               err = -ENOENT;
+               goto out_put_prog;
+       }
 
        raw_tp = kzalloc(sizeof(*raw_tp), GFP_USER);
        if (!raw_tp) {
@@ -1834,38 +1869,27 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
                goto out_put_btp;
        }
        raw_tp->btp = btp;
-
-       prog = bpf_prog_get(attr->raw_tracepoint.prog_fd);
-       if (IS_ERR(prog)) {
-               err = PTR_ERR(prog);
-               goto out_free_tp;
-       }
-       if (prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT &&
-           prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE) {
-               err = -EINVAL;
-               goto out_put_prog;
-       }
+       raw_tp->prog = prog;
 
        err = bpf_probe_register(raw_tp->btp, prog);
        if (err)
-               goto out_put_prog;
+               goto out_free_tp;
 
-       raw_tp->prog = prog;
        tp_fd = anon_inode_getfd("bpf-raw-tracepoint", &bpf_raw_tp_fops, raw_tp,
                                 O_CLOEXEC);
        if (tp_fd < 0) {
                bpf_probe_unregister(raw_tp->btp, prog);
                err = tp_fd;
-               goto out_put_prog;
+               goto out_free_tp;
        }
        return tp_fd;
 
-out_put_prog:
-       bpf_prog_put(prog);
 out_free_tp:
        kfree(raw_tp);
 out_put_btp:
        bpf_put_raw_tracepoint(btp);
+out_put_prog:
+       bpf_prog_put(prog);
        return err;
 }