|
@@ -1840,8 +1840,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
|
|
|
msg.msg_iov = &iov;
|
|
|
iov.iov_len = size;
|
|
|
iov.iov_base = ubuf;
|
|
|
- msg.msg_name = (struct sockaddr *)&address;
|
|
|
- msg.msg_namelen = sizeof(address);
|
|
|
+ /* Save some cycles and don't copy the address if not needed */
|
|
|
+ msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
|
|
|
+ /* We assume all kernel code knows the size of sockaddr_storage */
|
|
|
+ msg.msg_namelen = 0;
|
|
|
if (sock->file->f_flags & O_NONBLOCK)
|
|
|
flags |= MSG_DONTWAIT;
|
|
|
err = sock_recvmsg(sock, &msg, size, flags);
|
|
@@ -2221,16 +2223,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * Save the user-mode address (verify_iovec will change the
|
|
|
- * kernel msghdr to use the kernel address space)
|
|
|
+ /* Save the user-mode address (verify_iovec will change the
|
|
|
+ * kernel msghdr to use the kernel address space)
|
|
|
*/
|
|
|
-
|
|
|
uaddr = (__force void __user *)msg_sys->msg_name;
|
|
|
uaddr_len = COMPAT_NAMELEN(msg);
|
|
|
- if (MSG_CMSG_COMPAT & flags) {
|
|
|
+ if (MSG_CMSG_COMPAT & flags)
|
|
|
err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
|
|
|
- } else
|
|
|
+ else
|
|
|
err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
|
|
|
if (err < 0)
|
|
|
goto out_freeiov;
|
|
@@ -2239,6 +2239,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
|
|
|
cmsg_ptr = (unsigned long)msg_sys->msg_control;
|
|
|
msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
|
|
|
|
|
|
+ /* We assume all kernel code knows the size of sockaddr_storage */
|
|
|
+ msg_sys->msg_namelen = 0;
|
|
|
+
|
|
|
if (sock->file->f_flags & O_NONBLOCK)
|
|
|
flags |= MSG_DONTWAIT;
|
|
|
err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
|