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)); _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"