Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jan 2016 16:26:39 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r293537 - stable/10/sys/compat/linux
Message-ID:  <201601091626.u09GQdsZ038509@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sat Jan  9 16:26:39 2016
New Revision: 293537
URL: https://svnweb.freebsd.org/changeset/base/293537

Log:
  MFC r283433:
  
  Rewrite linux_recvfrom. To avoid double conversion of sockaddr use
  kern_recvit() directly.
  And check fromlen parameter before sockaddr copyin and conversion.

Modified:
  stable/10/sys/compat/linux/linux_socket.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/compat/linux/linux_socket.c
==============================================================================
--- stable/10/sys/compat/linux/linux_socket.c	Sat Jan  9 16:25:30 2016	(r293536)
+++ stable/10/sys/compat/linux/linux_socket.c	Sat Jan  9 16:26:39 2016	(r293537)
@@ -428,7 +428,6 @@ linux_to_bsd_sockaddr(struct sockaddr *a
 	return (error);
 }
 
-
 static int
 linux_sa_put(struct osockaddr *osa)
 {
@@ -1027,41 +1026,50 @@ linux_sendto(struct thread *td, struct l
 int
 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
 {
-	struct recvfrom_args /* {
-		int	s;
-		caddr_t	buf;
-		size_t	len;
-		int	flags;
-		struct sockaddr * __restrict from;
-		socklen_t * __restrict fromlenaddr;
-	} */ bsd_args;
-	size_t len;
+	struct msghdr msg;
+	struct iovec aiov;
 	int error;
 
-	if ((error = copyin(PTRIN(args->fromlen), &len, sizeof(size_t))))
-		return (error);
+	if (PTRIN(args->fromlen) != NULL) {
+		error = copyin(PTRIN(args->fromlen), &msg.msg_namelen,
+		    sizeof(msg.msg_namelen));
+		if (error != 0)
+			return (error);
 
-	bsd_args.s = args->s;
-	bsd_args.buf = PTRIN(args->buf);
-	bsd_args.len = args->len;
-	bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
-	/* XXX: */
-	bsd_args.from = (struct sockaddr * __restrict)PTRIN(args->from);
-	bsd_args.fromlenaddr = PTRIN(args->fromlen);/* XXX */
-	
-	linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len);
-	error = sys_recvfrom(td, &bsd_args);
-	bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from);
-	
-	if (error)
+		error = linux_to_bsd_sockaddr((struct sockaddr *)PTRIN(args->from),
+		    msg.msg_namelen);
+		if (error != 0)
+			return (error);
+	} else
+		msg.msg_namelen = 0;
+
+	msg.msg_name = (struct sockaddr * __restrict)PTRIN(args->from);
+	msg.msg_iov = &aiov;
+	msg.msg_iovlen = 1;
+	aiov.iov_base = PTRIN(args->buf);
+	aiov.iov_len = args->len;
+	msg.msg_control = 0;
+	msg.msg_flags = linux_to_bsd_msg_flags(args->flags);
+
+	error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, NULL);
+	if (error != 0)
 		return (error);
-	if (args->from) {
-		error = linux_sa_put((struct osockaddr *)
+
+	if (PTRIN(args->from) != NULL) {
+		error = bsd_to_linux_sockaddr((struct sockaddr *)
 		    PTRIN(args->from));
-		if (error)
+		if (error != 0)
 			return (error);
+
+		error = linux_sa_put((struct osockaddr *)
+		    PTRIN(args->from));
 	}
-	return (0);
+
+	if (PTRIN(args->fromlen) != NULL)
+		error = copyout(&msg.msg_namelen, PTRIN(args->fromlen),
+		    sizeof(msg.msg_namelen));
+
+	return (error);
 }
 
 int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601091626.u09GQdsZ038509>