]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bpf: add BPF token support to BPF_BTF_LOAD command
authorAndrii Nakryiko <andrii@kernel.org>
Thu, 30 Nov 2023 18:52:17 +0000 (10:52 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 6 Dec 2023 18:02:59 +0000 (10:02 -0800)
Accept BPF token FD in BPF_BTF_LOAD command to allow BTF data loading
through delegated BPF token. BTF loading is a pretty straightforward
operation, so as long as BPF token is created with allow_cmds granting
BPF_BTF_LOAD command, kernel proceeds to parsing BTF data and creating
BTF object.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231130185229.2688956-6-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
kernel/bpf/syscall.c
tools/include/uapi/linux/bpf.h

index 0bba3392b17ac3aba58cffbb6719782722ee9dcf..9f9989e0d062b3756a7b0c5148badbbfe0ff8db2 100644 (file)
@@ -1616,6 +1616,7 @@ union bpf_attr {
                 * truncated), or smaller (if log buffer wasn't filled completely).
                 */
                __u32           btf_log_true_size;
+               __u32           btf_token_fd;
        };
 
        struct {
index 22e14124cd6130129a6a81981a8c739091c2e90a..d87c5c27cde31a9648a2efbb212eb5b809407152 100644 (file)
@@ -4777,15 +4777,31 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
        return err;
 }
 
-#define BPF_BTF_LOAD_LAST_FIELD btf_log_true_size
+#define BPF_BTF_LOAD_LAST_FIELD btf_token_fd
 
 static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
 {
+       struct bpf_token *token = NULL;
+
        if (CHECK_ATTR(BPF_BTF_LOAD))
                return -EINVAL;
 
-       if (!bpf_capable())
+       if (attr->btf_token_fd) {
+               token = bpf_token_get_from_fd(attr->btf_token_fd);
+               if (IS_ERR(token))
+                       return PTR_ERR(token);
+               if (!bpf_token_allow_cmd(token, BPF_BTF_LOAD)) {
+                       bpf_token_put(token);
+                       token = NULL;
+               }
+       }
+
+       if (!bpf_token_capable(token, CAP_BPF)) {
+               bpf_token_put(token);
                return -EPERM;
+       }
+
+       bpf_token_put(token);
 
        return btf_new_fd(attr, uattr, uattr_size);
 }
index 0bba3392b17ac3aba58cffbb6719782722ee9dcf..9f9989e0d062b3756a7b0c5148badbbfe0ff8db2 100644 (file)
@@ -1616,6 +1616,7 @@ union bpf_attr {
                 * truncated), or smaller (if log buffer wasn't filled completely).
                 */
                __u32           btf_log_true_size;
+               __u32           btf_token_fd;
        };
 
        struct {