svn commit: r293537 - stable/10/sys/compat/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sat Jan 9 16:26:40 UTC 2016
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
More information about the svn-src-stable-10
mailing list