Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 May 2015 16:26:55 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r283433 - head/sys/compat/linux
Message-ID:  <201505241626.t4OGQt4V084379@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sun May 24 16:26:55 2015
New Revision: 283433
URL: https://svnweb.freebsd.org/changeset/base/283433

Log:
  Rewrite linux_recvfrom. To avoid double conversion of sockaddr use
  kern_recvit() directly.
  And check fromlen parameter before sockaddr copyin and conversion.
  
  Differential Revision:	https://reviews.freebsd.org/D1082

Modified:
  head/sys/compat/linux/linux_socket.c

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Sun May 24 16:25:44 2015	(r283432)
+++ head/sys/compat/linux/linux_socket.c	Sun May 24 16:26:55 2015	(r283433)
@@ -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?201505241626.t4OGQt4V084379>