Hi,
Here's v3 of the bpf syscall patches, following on from the RFC[1], v1[2] and v2[3].
The bpf syscall is updated to propagate user pointers as capabilities in the pure-capability kernel-user ABI (PCuABI). It also includes an approach to support the existing aarch64 ABI (compat64).
One complication here is from the fact this syscall supports many multiplexed sub-commands, some of which are themselves multiplexed with a number of nested multiplexed options.
A further complication is that the existing syscall uses a trick of storing user pointers as u64 to avoid needing a compat handler for 32-bit systems. To retain compatibility with the aarch64 ABI and add Morello support, special compat64 conversion and handling is implemented.
Inbound (userspace->kernel) conversion between compat64/native struct layouts is handled upfront on entry to the syscall (with the exception of bpf_xyz_info structs). This minimises changes to subcommand handlers. Some subcommands require conversion back out to userspace and that is by necessity handled where it occurs.
Patch 1 is not essential to this series but it's a nice debug feature to have and works[4]. It enables BPF_PROG_TYPE_TRACEPOINT which many eBPF kselftests use.
Patches 5,6,8 implement the core compat64 handling. Each commit compiles cleanly but relevant parts will be broken inbetween.
Patch 9 fixes the CHECK_ATTR macro to also check configs passed in via compat64.
Patch 11 finally enables capabilities in the kernel.
Patches 12,13 handles uaccess that occurs in two eBPF helper functions.
The rest are setup/helper functions.
Testing wise, see associated LTP changes below as posted to LTP mailing list[5]. The eBPF LTP tests are fairly minimal and test only a small part of the changes here. There's a new test to test CHECK_ATTR from patch 9.
The kernel kselftests contain many more extensive eBPF tests. They can be built fairly easily natively on aarch64 which is useful for testing compat64. More work needs to be done here though to: a) enable out-of-tree cross-compilation for purecap as well as x86->aarch64 b) replace ptr_to_u64() with casts to uintptr_t in tests c) general libbpf/bpftool enablement and fixes since many tests rely on this d) CONFIG_DEBUG_INFO_BTF required for many tests but this requires the build system to have a recent version of pahole tool
Next steps once we have the core kernel support would be porting libbpf and bpftool for purecap plus work on enabling kselftests as above.
Kernel branch available at: https://git.morello-project.org/zdleaf/linux/-/tree/morello/bpf_v3
Associated LTP test/changes at: https://git.morello-project.org/zdleaf/morello-linux-test-project/-/tree/mor...
Thanks,
Zach
[1] [RFC PATCH 0/9] update bpf syscall for PCuABI/compat64 https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... [2] [PATCH 00/10] update bpf syscall for PCuABI/compat64 https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... [3] [PATCH v2 00/12] update bpf syscall for PCuABI/compat64 https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... [4] [PATCH v3 0/5] Restore syscall tracing on Morello https://op-lists.linaro.org/archives/list/linux-morello@op-lists.linaro.org/... [5] [PATCH 0/3] add eBPF support https://op-lists.linaro.org/archives/list/linux-morello-ltp@op-lists.linaro....
-----------------------------------------------------------------------
v3: - Renamed all {is,in}_32bit_... to compat32, e.g. is_32bit_compat_task -> is_compat32 task, same for 64bit versions - Removed dispatch_bpf() + bpf_check_perms() and merged back into __sys_bpf - they no longer need to be split now we have no separate compat64 handler - Ensured we memset(0)/zero initialise all compat/non-compat structs for bpf_attr, bpf_{prog,link,btf}_info as appropriate when copying in/out from userspace - Switched order of first two arguments of bpf_put_uattr() to align with bpfptr_put_uattr() and more closely match put_user() - Moved #include <linux/bpf_compat.h> into bpf.h - Moved bpf_copy_{to,from}_user_with_ptr to bpf.h - Renamed bpf_uattr_compat_ptr macro to bpf_compat_ptr_field - Removed const arguments for bpf_copy_from_user(_task) helpers - Fixed pointer type mismatch warnings in void *ptr = in_compat64_syscall() ? type1 : type2; pattern - Replace temporary #define bpfptr_copy with in_compat64_syscall conditional in bpfptr.h:copy_from_bpfptr_with_ptr - only use _with_ptr in purecap
v2: - Fixed copy_from_bpfptr_offset_with_ptr - this no longer uses sockptr as of 6.1 (see patch 9) - Rebase on 6.4 - new struct members need conversion/handling: - New BPF_PROG_TYPE_NETFILTER + associated bpf_attr BPF_LINK_CREATE members - New bpf_link_info types BPF_LINK_TYPE_NETFILTER + BPF_LINK_TYPE_STRUCT_OPS - Renamed in_32bit_compat_syscall() to in_compat32_syscall() and added in_compat64_syscall() - Handled uaccess from bpf helper programs bpf/helpers.c:bpf_copy_from_user + bpf_copy_from_user_task - Added new stddef.h macro copy_field() to simplify conversion assignments
- bpf: compat64: add handler and convert bpf_attr in - Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use copy_bpf_attr_from_user() helper function for inbound compat conversion - This removes the __sys_compat_bpf compat64 handler, now using the existing __sys_bpf + in_compat64_syscall() for reduced diff size, less duplication and clearer code - Conversion now happens in copy_bpf_attr_from_user() for better encapsulation + stack usage
- bpf: compat64: bpf_attr convert out - Renamed PUT_USER_ATTR() to bpf_put_uattr() + moved to bpf.h - Introduced bpfptr_put_uattr() in bpfptr.h - Originally missed handling cases writing out to userspace with copy_to_bpfptr_offset() - now replaced with new bpfptr_put_uattr() macro - 6.4 now has a new field showing what log size will be needed - see 47a71c1f9af0 ("bpf: Add log_true_size output field to return necessary log buffer size") - This also requires new macro bpf_field_exists() to handle compat64 when checking that userspace supports this new field
- bpf: compat64: handle bpf_xyz_info - Simplified bpf_link_info conversion handling using memcpy - Removed bpf_map_info patch since struct is the same in compat64/native (no ptrs) - Replaced #ifdef CONFIG_COMPAT64 with in_compat64_syscall() + use copy_bpf_xyz_info_{from,to}_user() helper functions for compat conversions - Merged bpf_{btf,prog,link}_info into a single patch
- bpf: use user pointer types in uAPI structs - Added new compat_uptr_to_kern() macro to simplify casting/converting in compat ptrs - Usage of copy_{to,from}_user_with_ptr variants now correctly applied with new helpers
-----------------------------------------------------------------------
Zachary Leaf (13): arm64: morello: enable syscall tracing arch: rename to 32bit_compat to compat32 arch: add compat helpers specific to 64-bit stddef: introduce copy_field helper bpf: compat64: add handler and convert bpf_attr in bpf: compat64: bpf_attr convert out bpf/btf: move zero check into btf.c bpf: compat64: handle bpf_{btf,prog,link}_info bpf: compat64: support CHECK_ATTR macro bpf: copy_{to,from}_user_with_ptr helpers bpf: use user pointer types in uAPI structs bpf: use addr for bpf_copy_from_user_with_task bpf: use addr for bpf_copy_from_user
.../morello_transitional_pcuabi_defconfig | 2 +- arch/arm64/include/asm/compat.h | 11 +- arch/arm64/include/asm/ftrace.h | 2 +- arch/arm64/include/asm/mmu_context.h | 2 +- arch/arm64/include/asm/syscall.h | 6 +- arch/arm64/kernel/fpsimd.c | 6 +- arch/arm64/kernel/hw_breakpoint.c | 2 +- arch/arm64/kernel/perf_regs.c | 2 +- arch/arm64/kernel/pointer_auth.c | 6 +- arch/arm64/kernel/process.c | 16 +- arch/arm64/kernel/ptrace.c | 10 +- arch/arm64/kernel/signal.c | 2 +- arch/arm64/kernel/syscall.c | 2 +- arch/mips/include/asm/compat.h | 2 +- arch/parisc/include/asm/compat.h | 2 +- arch/powerpc/include/asm/compat.h | 2 +- arch/s390/include/asm/compat.h | 2 +- arch/sparc/include/asm/compat.h | 4 +- arch/x86/include/asm/compat.h | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 2 +- drivers/input/input.c | 2 +- drivers/media/rc/bpf-lirc.c | 6 +- fs/ext4/dir.c | 2 +- fs/nfs/dir.c | 2 +- include/linux/bpf.h | 22 + include/linux/bpf_compat.h | 415 +++++++++ include/linux/bpfptr.h | 30 +- include/linux/compat.h | 16 +- include/linux/stddef.h | 3 + include/uapi/linux/bpf.h | 94 +- kernel/bpf/bpf_iter.c | 2 +- kernel/bpf/btf.c | 105 ++- kernel/bpf/cgroup.c | 9 +- kernel/bpf/hashtab.c | 12 +- kernel/bpf/helpers.c | 9 +- kernel/bpf/net_namespace.c | 6 +- kernel/bpf/offload.c | 2 +- kernel/bpf/syscall.c | 871 ++++++++++++++---- kernel/bpf/verifier.c | 20 +- kernel/time/time.c | 2 +- kernel/trace/bpf_trace.c | 6 +- mm/util.c | 2 +- net/bpf/bpf_dummy_struct_ops.c | 8 +- net/bpf/test_run.c | 31 +- net/core/sock_map.c | 6 +- 46 files changed, 1425 insertions(+), 345 deletions(-) create mode 100644 include/linux/bpf_compat.h
-- 2.34.1