On 12/09/2023 11:51, Zachary Leaf wrote:
In PCuABI, when copying a block of memory to/from userspace containing capabilities/pointers, the copy_{to,from}_user_with_ptr variants need to be used to ensure capabilities are preserved in full.
Introduce bpf specific helper methods/macros to support this.
Since compat64 syscalls do not contain capabilities, the _with_ptr variants are not required in the in_compat64_syscall() case.
Signed-off-by: Zachary Leaf zachary.leaf@arm.com
include/linux/bpf_compat.h | 8 ++++++++ include/linux/bpfptr.h | 13 +++++++++++++ 2 files changed, 21 insertions(+)
diff --git a/include/linux/bpf_compat.h b/include/linux/bpf_compat.h index 710815417a27..9e16f7f5eda6 100644 --- a/include/linux/bpf_compat.h +++ b/include/linux/bpf_compat.h @@ -1,6 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2023 Arm Ltd */ +#define bpf_copy_from_user_with_ptr(dest, src, size) \
- (in_compat64_syscall() ? copy_from_user(dest, src, size) \
: copy_from_user_with_ptr(dest, src, size))
+#define bpf_copy_to_user_with_ptr(dest, src, size) \
- (in_compat64_syscall() ? copy_to_user(dest, src, size) \
: copy_to_user_with_ptr(dest, src, size))
I think these belong to bpf.h, like bpf_put_uattr and friends.
Kevin
union compat_bpf_attr { struct { /* anonymous struct used by BPF_MAP_CREATE command */ __u32 map_type; /* one of enum bpf_map_type */ diff --git a/include/linux/bpfptr.h b/include/linux/bpfptr.h index 7fdf9692d76e..f6828c5f7858 100644 --- a/include/linux/bpfptr.h +++ b/include/linux/bpfptr.h @@ -62,11 +62,24 @@ static inline int copy_from_bpfptr_offset(void *dst, bpfptr_t src, return copy_from_kernel_nofault(dst, src.kernel + offset, size); } +static inline int copy_from_bpfptr_offset_with_ptr(void *dst, bpfptr_t src,
size_t offset, size_t size)
+{
- if (!bpfptr_is_kernel(src))
return copy_from_user_with_ptr(dst, src.user + offset, size);
- return copy_from_kernel_nofault(dst, src.kernel + offset, size);
+}
static inline int copy_from_bpfptr(void *dst, bpfptr_t src, size_t size) { return copy_from_bpfptr_offset(dst, src, 0, size); } +static inline int copy_from_bpfptr_with_ptr(void *dst, bpfptr_t src, size_t size) +{
- return copy_from_bpfptr_offset_with_ptr(dst, src, 0, size);
+}
static inline int copy_to_bpfptr_offset(bpfptr_t dst, size_t offset, const void *src, size_t size) {