Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Keep BPF_PROG_LOAD permission checks clear of validations

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

authored by

Andrii Nakryiko and committed by
Daniel Borkmann
7f6719f7 6c3eba1c

+9 -12
+9 -12
kernel/bpf/syscall.c
··· 2550 2550 struct btf *attach_btf = NULL; 2551 2551 int err; 2552 2552 char license[128]; 2553 - bool is_gpl; 2554 2553 2555 2554 if (CHECK_ATTR(BPF_PROG_LOAD)) 2556 2555 return -EINVAL; ··· 2567 2568 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) && 2568 2569 !bpf_capable()) 2569 2570 return -EPERM; 2570 - 2571 - /* copy eBPF program license from user space */ 2572 - if (strncpy_from_bpfptr(license, 2573 - make_bpfptr(attr->license, uattr.is_kernel), 2574 - sizeof(license) - 1) < 0) 2575 - return -EFAULT; 2576 - license[sizeof(license) - 1] = 0; 2577 - 2578 - /* eBPF programs must be GPL compatible to use GPL-ed functions */ 2579 - is_gpl = license_is_gpl_compatible(license); 2580 2571 2581 2572 /* Intent here is for unprivileged_bpf_disabled to block BPF program 2582 2573 * creation for unprivileged users; other actions depend ··· 2660 2671 make_bpfptr(attr->insns, uattr.is_kernel), 2661 2672 bpf_prog_insn_size(prog)) != 0) 2662 2673 goto free_prog_sec; 2674 + /* copy eBPF program license from user space */ 2675 + if (strncpy_from_bpfptr(license, 2676 + make_bpfptr(attr->license, uattr.is_kernel), 2677 + sizeof(license) - 1) < 0) 2678 + goto free_prog_sec; 2679 + license[sizeof(license) - 1] = 0; 2680 + 2681 + /* eBPF programs must be GPL compatible to use GPL-ed functions */ 2682 + prog->gpl_compatible = license_is_gpl_compatible(license) ? 1 : 0; 2663 2683 2664 2684 prog->orig_prog = NULL; 2665 2685 prog->jited = 0; 2666 2686 2667 2687 atomic64_set(&prog->aux->refcnt, 1); 2668 - prog->gpl_compatible = is_gpl ? 1 : 0; 2669 2688 2670 2689 if (bpf_prog_is_dev_bound(prog->aux)) { 2671 2690 err = bpf_prog_dev_bound_init(prog, attr);