The purpose of the bpf_copy_from_user_with_task eBPF helper is to copy user data from the provided task. Since __user *ptrs are only valid for the current task/process, what is actually being passed in here is an address. access_process_vm is then used to access that address given the task specified by the task_struct.
Additionally, this helper is called from an eBPF program, which does not support capabilities. It is therefore unable to pass in a capability as a __user ptr in PCuABI in the first place.
The use case of this helper is to read arbitrary user memory, as used by security or monitoring eBPF programs. There is therefore no requirement to check user capabilities here. Loading of eBPF applications using this helper type is already strictly limited to privileged/root users.
In addition, access_process_vm() is not uaccess in the usual sense, as uaccess is about accessing the current process. This type of access is not currently checked in PCuABI.
Change the inbound type from __user * to ptraddr_t and remove the TODO since no capability checks are required here.
Signed-off-by: Zachary Leaf zachary.leaf@arm.com --- kernel/bpf/helpers.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 1362d7736a93..4910d7b88239 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -670,7 +670,7 @@ const struct bpf_func_proto bpf_copy_from_user_proto = { };
BPF_CALL_5(bpf_copy_from_user_task, void *, dst, u32, size, - const void __user *, user_ptr, struct task_struct *, tsk, u64, flags) + ptraddr_t, addr, struct task_struct *, tsk, u64, flags) { int ret;
@@ -681,8 +681,7 @@ BPF_CALL_5(bpf_copy_from_user_task, void *, dst, u32, size, if (unlikely(!size)) return 0;
- /* TODO [PCuABI] - capability checks for uaccess */ - ret = access_process_vm(tsk, user_ptr_addr(user_ptr), dst, size, 0); + ret = access_process_vm(tsk, addr, dst, size, 0); if (ret == size) return 0;