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 <tmueller at sysgo dot com> [1]
Reviewed by:	kib@
Approved by:	re (gjb, kib)
MFC after:	3 days
This commit is contained in:
Dmitry Chagin 2016-06-26 16:59:59 +00:00
parent ab3373140d
commit 3a49978f45

View File

@ -1054,18 +1054,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;