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-all
mailing list