]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Keep BPF_PROG_LOAD permission checks clear of validations
authorAndrii Nakryiko <andrii@kernel.org>
Tue, 13 Jun 2023 22:35:33 +0000 (15:35 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 19 Jun 2023 12:04:04 +0000 (14:04 +0200)
Move out flags validation and license checks out of the permission
checks. They were intermingled, which makes subsequent changes harder.
Clean this up: perform straightforward flag validation upfront, and
fetch and check license later, right where we use it. Also consolidate
capabilities check in one block, right after basic attribute sanity
checks.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/20230613223533.3689589-5-andrii@kernel.org
kernel/bpf/syscall.c

index 658d1154f221692f0c53148fd0ff96031d97024e..a75c54b6f8a33ace98b4d4079441f04e6873aa93 100644 (file)
@@ -2550,7 +2550,6 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
        struct btf *attach_btf = NULL;
        int err;
        char license[128];
-       bool is_gpl;
 
        if (CHECK_ATTR(BPF_PROG_LOAD))
                return -EINVAL;
@@ -2569,16 +2568,6 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
            !bpf_capable())
                return -EPERM;
 
-       /* copy eBPF program license from user space */
-       if (strncpy_from_bpfptr(license,
-                               make_bpfptr(attr->license, uattr.is_kernel),
-                               sizeof(license) - 1) < 0)
-               return -EFAULT;
-       license[sizeof(license) - 1] = 0;
-
-       /* eBPF programs must be GPL compatible to use GPL-ed functions */
-       is_gpl = license_is_gpl_compatible(license);
-
        /* Intent here is for unprivileged_bpf_disabled to block BPF program
         * creation for unprivileged users; other actions depend
         * on fd availability and access to bpffs, so are dependent on
@@ -2671,12 +2660,20 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
                             make_bpfptr(attr->insns, uattr.is_kernel),
                             bpf_prog_insn_size(prog)) != 0)
                goto free_prog_sec;
+       /* copy eBPF program license from user space */
+       if (strncpy_from_bpfptr(license,
+                               make_bpfptr(attr->license, uattr.is_kernel),
+                               sizeof(license) - 1) < 0)
+               goto free_prog_sec;
+       license[sizeof(license) - 1] = 0;
+
+       /* eBPF programs must be GPL compatible to use GPL-ed functions */
+       prog->gpl_compatible = license_is_gpl_compatible(license) ? 1 : 0;
 
        prog->orig_prog = NULL;
        prog->jited = 0;
 
        atomic64_set(&prog->aux->refcnt, 1);
-       prog->gpl_compatible = is_gpl ? 1 : 0;
 
        if (bpf_prog_is_dev_bound(prog->aux)) {
                err = bpf_prog_dev_bound_init(prog, attr);