Similar to the syscall common attrs support for map_create [1], add the
syscall common attrs support for link_create.

Create and finalize the internal verifier log instance.

Then, report the error messages for invalid prog fd and invalid attach
type.

Links:
[1] https://lore.kernel.org/bpf/[email protected]/

Signed-off-by: Leon Hwang <[email protected]>
---
 kernel/bpf/syscall.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0f27604a54aa..252b479937a4 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5839,10 +5839,13 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
 }
 
 #define BPF_LINK_CREATE_LAST_FIELD link_create.uprobe_multi.path_fd
-static int link_create(union bpf_attr *attr, bpfptr_t uattr)
+static int link_create(union bpf_attr *attr, bpfptr_t uattr, struct 
bpf_common_attr *attr_common,
+                      bpfptr_t uattr_common, u32 size_common)
 {
+       struct bpf_verifier_log *log;
+       struct bpf_log_attr attr_log;
        struct bpf_prog *prog;
-       int ret;
+       int ret, err;
 
        if (CHECK_ATTR(BPF_LINK_CREATE))
                return -EINVAL;
@@ -5850,14 +5853,24 @@ static int link_create(union bpf_attr *attr, bpfptr_t 
uattr)
        if (attr->link_create.attach_type == BPF_STRUCT_OPS)
                return bpf_struct_ops_link_create(attr);
 
+       log = bpf_log_attr_create_vlog(&attr_log, attr_common, uattr_common, 
size_common);
+       if (IS_ERR(log))
+               return PTR_ERR(log);
+
        prog = bpf_prog_get(attr->link_create.prog_fd);
-       if (IS_ERR(prog))
-               return PTR_ERR(prog);
+       if (IS_ERR(prog)) {
+               bpf_log(log, "Invalid prog_fd.\n");
+               ret = PTR_ERR(prog);
+               prog = NULL;
+               goto out;
+       }
 
        ret = bpf_prog_attach_check_attach_type(prog,
                                                attr->link_create.attach_type);
-       if (ret)
+       if (ret) {
+               bpf_log(log, "Invalid attach_type.\n");
                goto out;
+       }
 
        switch (prog->type) {
        case BPF_PROG_TYPE_CGROUP_SKB:
@@ -5940,7 +5953,14 @@ static int link_create(union bpf_attr *attr, bpfptr_t 
uattr)
        }
 
 out:
-       if (ret < 0)
+       /* preserve original error even if log finalization is successful */
+       err = bpf_log_attr_finalize(&attr_log, log);
+       if (err)
+               ret = err;
+
+       kfree(log);
+
+       if (ret < 0 && prog)
                bpf_prog_put(prog);
        return ret;
 }
@@ -6513,7 +6533,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, 
unsigned int size,
                err = bpf_map_do_batch(&attr, uattr.user, BPF_MAP_DELETE_BATCH);
                break;
        case BPF_LINK_CREATE:
-               err = link_create(&attr, uattr);
+               err = link_create(&attr, uattr, &attr_common, uattr_common, 
size_common);
                break;
        case BPF_LINK_UPDATE:
                err = link_update(&attr);
-- 
2.55.0


Reply via email to