From c04eec0cf0d22693afb178c43250f77699c18964 Mon Sep 17 00:00:00 2001 From: dchagin Date: Wed, 29 Jun 2016 06:04:45 +0000 Subject: MFC r302213: Fix a bug introduced in r283433. [1] Remove unneeded sockaddr conversion before kern_recvit() call as the from argument is used to record result (the source address of the received message) only. [2] In Linux the type of msg_namelen member of struct msghdr is signed but native msg_namelen has a unsigned type (socklen_t). So use the proper storage to fetch fromlen from userspace and than check the user supplied value and return EINVAL if it is less than 0 as a Linux do. Reported by: Thomas Mueller [1] Tested by: Thomas Mueller [both] Reviewed by: kib@ --- sys/compat/linux/linux_socket.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'sys/compat/linux/linux_socket.c') diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index bc543c7..e340873 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1040,18 +1040,16 @@ linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args) { struct msghdr msg; struct iovec aiov; - int error; + int error, fromlen; if (PTRIN(args->fromlen) != NULL) { - error = copyin(PTRIN(args->fromlen), &msg.msg_namelen, - sizeof(msg.msg_namelen)); - if (error != 0) - return (error); - - error = linux_to_bsd_sockaddr((struct sockaddr *)PTRIN(args->from), - msg.msg_namelen); + error = copyin(PTRIN(args->fromlen), &fromlen, + sizeof(fromlen)); if (error != 0) return (error); + if (fromlen < 0) + return (EINVAL); + msg.msg_namelen = fromlen; } else msg.msg_namelen = 0; -- cgit v1.1