svn commit: r313684 - head/sys/compat/linux

Dmitry Chagin dchagin at FreeBSD.org
Sun Feb 12 15:22:52 UTC 2017


Author: dchagin
Date: Sun Feb 12 15:22:50 2017
New Revision: 313684
URL: https://svnweb.freebsd.org/changeset/base/313684

Log:
  Fix r313284.
  
  Members of the syscall argument structures are padded to a word size. So,
  for COMPAT_LINUX32 we should convert user supplied system call arguments
  which is 32-bit in that case to the array of register_t.
  
  Reported by:	Oleg V. Nauman
  MFC after:	1 week

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

Modified: head/sys/compat/linux/linux_socket.c
==============================================================================
--- head/sys/compat/linux/linux_socket.c	Sun Feb 12 09:49:44 2017	(r313683)
+++ head/sys/compat/linux/linux_socket.c	Sun Feb 12 15:22:50 2017	(r313684)
@@ -1683,39 +1683,45 @@ linux_getsockopt(struct thread *td, stru
 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
 
 /* Argument list sizes for linux_socketcall */
-
-#define LINUX_AL(x) ((x) * sizeof(l_ulong))
-
-static const unsigned char lxs_args[] = {
-	LINUX_AL(0) /* unused*/,	LINUX_AL(3) /* socket */,
-	LINUX_AL(3) /* bind */,		LINUX_AL(3) /* connect */,
-	LINUX_AL(2) /* listen */,	LINUX_AL(3) /* accept */,
-	LINUX_AL(3) /* getsockname */,	LINUX_AL(3) /* getpeername */,
-	LINUX_AL(4) /* socketpair */,	LINUX_AL(4) /* send */,
-	LINUX_AL(4) /* recv */,		LINUX_AL(6) /* sendto */,
-	LINUX_AL(6) /* recvfrom */,	LINUX_AL(2) /* shutdown */,
-	LINUX_AL(5) /* setsockopt */,	LINUX_AL(5) /* getsockopt */,
-	LINUX_AL(3) /* sendmsg */,	LINUX_AL(3) /* recvmsg */,
-	LINUX_AL(4) /* accept4 */,	LINUX_AL(5) /* recvmmsg */,
-	LINUX_AL(4) /* sendmmsg */
+static const unsigned char lxs_args_cnt[] = {
+	0 /* unused*/,		3 /* socket */,
+	3 /* bind */,		3 /* connect */,
+	2 /* listen */,		3 /* accept */,
+	3 /* getsockname */,	3 /* getpeername */,
+	4 /* socketpair */,	4 /* send */,
+	4 /* recv */,		6 /* sendto */,
+	6 /* recvfrom */,	2 /* shutdown */,
+	5 /* setsockopt */,	5 /* getsockopt */,
+	3 /* sendmsg */,	3 /* recvmsg */,
+	4 /* accept4 */,	5 /* recvmmsg */,
+	4 /* sendmmsg */
 };
-
-#define	LINUX_AL_SIZE	(nitems(lxs_args) - 1)
+#define	LINUX_ARGS_CNT		(nitems(lxs_args_cnt) - 1)
+#define	LINUX_ARG_SIZE(x)	(lxs_args_cnt[x] * sizeof(l_ulong))
 
 int
 linux_socketcall(struct thread *td, struct linux_socketcall_args *args)
 {
 	l_ulong a[6];
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	register_t l_args[6];
+#endif
 	void *arg;
 	int error;
 
-	if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE)
+	if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT)
 		return (EINVAL);
-	error = copyin(PTRIN(args->args), a, lxs_args[args->what]);
-	if (error)
+	error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what));
+	if (error != 0)
 		return (error);
 
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	for (int i = 0; i < lxs_args_cnt[args->what]; ++i)
+		l_args[i] = a[i];
+	arg = l_args;
+#else
 	arg = a;
+#endif
 	switch (args->what) {
 	case LINUX_SOCKET:
 		return (linux_socket(td, arg));


More information about the svn-src-head mailing list