Multiple fields of struct tcp_zerocopy_receive (address, copybuf_address, msg_control) are typed as __u64 even though they represent user pointers. For now let's create user pointers manually using uaddr_to_user_ptr(), but eventually the struct should be modified to represent the fields as __kernel_uintptr_t instead, allowing userspace to provide whole user pointers instead of just addresses.
Also address a user pointer conversion issue where we need to explicitly extract the address of struct msghdr::msg_control_user to store it in struct tcp_zerocopy_receive::msg_control (as it currently only represents an address).
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- net/ipv4/tcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8f5e605ea673..f5b69c347846 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2000,7 +2000,7 @@ static int receive_fallback_to_copy(struct sock *sk, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(READ, uaddr_to_user_ptr(copy_address), inq, &iov, &msg.msg_iter); if (err) return err; @@ -2034,7 +2034,7 @@ static int tcp_copy_straggler_data(struct tcp_zerocopy_receive *zc, if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(READ, uaddr_to_user_ptr(copy_address), copylen, &iov, &msg.msg_iter); if (err) return err; @@ -2163,7 +2163,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, struct msghdr cmsg_dummy;
msg_control_addr = (unsigned long)zc->msg_control; - cmsg_dummy.msg_control_user = (void __user *)msg_control_addr; + cmsg_dummy.msg_control_user = uaddr_to_user_ptr(msg_control_addr); cmsg_dummy.msg_controllen = (__kernel_size_t)zc->msg_controllen; cmsg_dummy.msg_flags = in_compat_syscall() @@ -2174,7 +2174,7 @@ static void tcp_zc_finalize_rx_tstamp(struct sock *sk, zc->msg_controllen == cmsg_dummy.msg_controllen) { tcp_recv_timestamp(&cmsg_dummy, sk, tss); zc->msg_control = (__u64) - ((uintptr_t)cmsg_dummy.msg_control_user); + user_ptr_addr(cmsg_dummy.msg_control_user); zc->msg_controllen = (__u64)cmsg_dummy.msg_controllen; zc->msg_flags = (__u32)cmsg_dummy.msg_flags;