diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/net/socket.c b/net/socket.c index 9f8cd744f0b0..06e8f3d1db2f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1744,8 +1744,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); @@ -2033,18 +2035,16 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, goto out_put; } - /* - * 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, (struct sockaddr *)&addr, VERIFY_WRITE); - } else + else err = verify_iovec(&msg_sys, iov, (struct sockaddr *)&addr, VERIFY_WRITE); @@ -2055,6 +2055,9 @@ SYSCALL_DEFINE3(recvmsg, int, fd, 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 = sock_recvmsg(sock, &msg_sys, total_len, flags); |