On 12/07/2023 12:18, Kevin Brodsky wrote:
On 08/06/2023 10:42, Zachary Leaf wrote:
In PCuABI, when copying a block of memory from userspace containing capabilities/pointers, the copy_from_user_with_ptr variant needs to be used to ensure pointers are preserved in full.
Introduce copy_from_x_with_ptr methods for bpfptr_t and sockptr_t to support this.
Signed-off-by: Zachary Leaf zachary.leaf@arm.com
include/linux/bpfptr.h | 12 ++++++++++++ include/linux/sockptr.h | 9 +++++++++ 2 files changed, 21 insertions(+)
diff --git a/include/linux/bpfptr.h b/include/linux/bpfptr.h index 79b2f78eec1a..407e25d608eb 100644 --- a/include/linux/bpfptr.h +++ b/include/linux/bpfptr.h @@ -54,11 +54,23 @@ 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)
+{
- return copy_from_sockptr_offset_with_ptr(dst, (sockptr_t) src, offset,
size);
I think you might have missed [1] when rebasing. copy_from_sockptr_offset() is no longer used by copy_from_bpfptr_offset(). I guess that means that we don't need copy_from_sockptr_offset_with_ptr() any more either?
Ah yep. Missed that rebasing from 5.18->6.1. Fixed.
Thanks, Zach
Kevin
[1] https://lore.kernel.org/bpf/20220727132905.45166-1-jinghao@linux.ibm.com/
+}
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) { diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h index bae5e2369b4f..08b17706b21a 100644 --- a/include/linux/sockptr.h +++ b/include/linux/sockptr.h @@ -50,6 +50,15 @@ static inline int copy_from_sockptr_offset(void *dst, sockptr_t src, return 0; } +static inline int copy_from_sockptr_offset_with_ptr(void *dst, sockptr_t src,
size_t offset, size_t size)
+{
- if (!sockptr_is_kernel(src))
return copy_from_user_with_ptr(dst, src.user + offset, size);
- memcpy(dst, src.kernel + offset, size);
- return 0;
+}
static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size) { return copy_from_sockptr_offset(dst, src, 0, size);