// SPDX-License-Identifier: GPL-2.0-only
/*
 * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c.
 *
 * Copyright (C) 2000		VA Linux Co
 * Copyright (C) 2000		Don Dugger <n0ano@valinux.com>
 * Copyright (C) 1999 		Arun Sharma <arun.sharma@intel.com>
 * Copyright (C) 1997,1998 	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 * Copyright (C) 1997 		David S. Miller (davem@caip.rutgers.edu)
 * Copyright (C) 2000		Hewlett-Packard Co.
 * Copyright (C) 2000		David Mosberger-Tang <davidm@hpl.hp.com>
 * Copyright (C) 2000,2001	Andi Kleen, SuSE Labs
 */

#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/file.h>
#include <linux/icmpv6.h>
#include <linux/socket.h>
#include <linux/syscalls.h>
#include <linux/filter.h>
#include <linux/compat.h>
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/export.h>

#include <net/scm.h>
#include <net/sock.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/uaccess.h>
#include <net/compat.h>

int __get_compat_msghdr(struct msghdr *kmsg,
			struct compat_msghdr __user *umsg,
			struct sockaddr __user **save_addr,
			compat_uptr_t *ptr, compat_size_t *len)
{
	struct compat_msghdr msg;
	ssize_t err;

	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
		return -EFAULT;

	kmsg->msg_flags = msg.msg_flags;
	kmsg->msg_namelen = msg.msg_namelen;

	if (!msg.msg_name)
		kmsg->msg_namelen = 0;

	if (kmsg->msg_namelen < 0)
		return -EINVAL;

	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
		kmsg->msg_namelen = sizeof(struct sockaddr_storage);

	kmsg->msg_control_is_user = true;
	kmsg->msg_control_user = compat_ptr(msg.msg_control);
	kmsg->msg_controllen = msg.msg_controllen;

	if (save_addr)
		*save_addr = compat_ptr(msg.msg_name);

	if (msg.msg_name && kmsg->msg_namelen) {
		if (!save_addr) {
			err = move_addr_to_kernel(compat_ptr(msg.msg_name),
						  kmsg->msg_namelen,
						  kmsg->msg_name);
			if (err < 0)
				return err;
		}
	} else {
		kmsg->msg_name = NULL;
		kmsg->msg_namelen = 0;
	}

	if (msg.msg_iovlen > UIO_MAXIOV)
		return -EMSGSIZE;

	kmsg->msg_iocb = NULL;
	*ptr = msg.msg_iov;
	*len = msg.msg_iovlen;
	return 0;
}

int get_compat_msghdr(struct msghdr *kmsg,
		      struct compat_msghdr __user *umsg,
		      struct sockaddr __user **save_addr,
		      struct iovec **iov)
{
	compat_uptr_t ptr;
	compat_size_t len;
	ssize_t err;

	err = __get_compat_msghdr(kmsg, umsg, save_addr, &ptr, &len);
	if (err)
		return err;

	err = import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr), len,
			   UIO_FASTIOV, iov, &kmsg->msg_iter);
	return err < 0 ? err : 0;
}

/* Bleech... */
#define CMSG_COMPAT_ALIGN(len)	ALIGN((len), sizeof(s32))

#define CMSG_COMPAT_DATA(cmsg)				\
	((void __user *)((char __user *)(cmsg) + sizeof(struct compat_cmsghdr)))
#define CMSG_COMPAT_SPACE(len)				\
	(sizeof(struct compat_cmsghdr) + CMSG_COMPAT_ALIGN(len))
#define CMSG_COMPAT_LEN(len)				\
	(sizeof(struct compat_cmsghdr) + (len))

#define CMSG_COMPAT_FIRSTHDR(msg)			\
	(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ?	\
	 (struct compat_cmsghdr __user *)((msg)->msg_control) :		\
	 (struct compat_cmsghdr __user *)NULL)

#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
	((ucmlen) >= sizeof(struct compat_cmsghdr) && \
	 (ucmlen) <= (unsigned long) \
	 ((mhdr)->msg_controllen - \
	  ((char __user *)(ucmsg) - (char __user *)(mhdr)->msg_control_user)))

static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
		struct compat_cmsghdr __user *cmsg, int cmsg_len)
{
	char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
	if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) >
			msg->msg_controllen)
		return NULL;
	return (struct compat_cmsghdr __user *)ptr;
}

/* There is a lot of hair here because the alignment rules (and
 * thus placement) of cmsg headers and length are different for
 * 32-bit apps.  -DaveM
 */
int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
			       unsigned char *stackbuf, int stackbuf_size)
{
	struct compat_cmsghdr __user *ucmsg;
	struct cmsghdr *kcmsg, *kcmsg_base;
	compat_size_t ucmlen;
	__kernel_size_t kcmlen, tmp;
	int err = -EFAULT;

	BUILD_BUG_ON(sizeof(struct compat_cmsghdr) !=
		     CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)));

	kcmlen = 0;
	kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
	ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
	while (ucmsg != NULL) {
		if (get_user(ucmlen, &ucmsg->cmsg_len))
			return -EFAULT;

		/* Catch bogons. */
		if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
			return -EINVAL;

		tmp = ((ucmlen - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
		tmp = CMSG_ALIGN(tmp);
		kcmlen += tmp;
		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
	}
	if (kcmlen == 0)
		return -EINVAL;

	/* The kcmlen holds the 64-bit version of the control length.
	 * It may not be modified as we do not stick it into the kmsg
	 * until we have successfully copied over all of the data
	 * from the user.
	 */
	if (kcmlen > stackbuf_size)
		kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
	if (kcmsg == NULL)
		return -ENOMEM;

	/* Now copy them over neatly. */
	memset(kcmsg, 0, kcmlen);
	ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
	while (ucmsg != NULL) {
		struct compat_cmsghdr cmsg;
		if (copy_from_user(&cmsg, ucmsg, sizeof(cmsg)))
			goto Efault;
		if (!CMSG_COMPAT_OK(cmsg.cmsg_len, ucmsg, kmsg))
			goto Einval;
		tmp = ((cmsg.cmsg_len - sizeof(*ucmsg)) + sizeof(struct cmsghdr));
		if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
			goto Einval;
		kcmsg->cmsg_len = tmp;
		kcmsg->cmsg_level = cmsg.cmsg_level;
		kcmsg->cmsg_type = cmsg.cmsg_type;
		tmp = CMSG_ALIGN(tmp);
		if (copy_from_user(CMSG_DATA(kcmsg),
				   CMSG_COMPAT_DATA(ucmsg),
				   (cmsg.cmsg_len - sizeof(*ucmsg))))
			goto Efault;

		/* Advance. */
		kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, cmsg.cmsg_len);
	}

	/*
	 * check the length of messages copied in is the same as the
	 * what we get from the first loop
	 */
	if ((char *)kcmsg - (char *)kcmsg_base != kcmlen)
		goto Einval;

	/* Ok, looks like we made it.  Hook it up and return success. */
	kmsg->msg_control = kcmsg_base;
	kmsg->msg_controllen = kcmlen;
	return 0;

Einval:
	err = -EINVAL;
Efault:
	if (kcmsg_base != (struct cmsghdr *)stackbuf)
		sock_kfree_s(sk, kcmsg_base, kcmlen);
	return err;
}

int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
{
	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
	struct compat_cmsghdr cmhdr;
	struct old_timeval32 ctv;
	struct old_timespec32 cts[3];
	int cmlen;

	if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
		kmsg->msg_flags |= MSG_CTRUNC;
		return 0; /* XXX: return error? check spec. */
	}

	if (!COMPAT_USE_64BIT_TIME) {
		if (level == SOL_SOCKET && type == SO_TIMESTAMP_OLD) {
			struct __kernel_old_timeval *tv = (struct __kernel_old_timeval *)data;
			ctv.tv_sec = tv->tv_sec;
			ctv.tv_usec = tv->tv_usec;
			data = &ctv;
			len = sizeof(ctv);
		}
		if (level == SOL_SOCKET &&
		    (type == SO_TIMESTAMPNS_OLD || type == SO_TIMESTAMPING_OLD)) {
			int count = type == SO_TIMESTAMPNS_OLD ? 1 : 3;
			int i;
			struct __kernel_old_timespec *ts = data;
			for (i = 0; i < count; i++) {
				cts[i].tv_sec = ts[i].tv_sec;
				cts[i].tv_nsec = ts[i].tv_nsec;
			}
			data = &cts;
			len = sizeof(cts[0]) * count;
		}
	}

	cmlen = CMSG_COMPAT_LEN(len);
	if (kmsg->msg_controllen < cmlen) {
		kmsg->msg_flags |= MSG_CTRUNC;
		cmlen = kmsg->msg_controllen;
	}
	cmhdr.cmsg_level = level;
	cmhdr.cmsg_type = type;
	cmhdr.cmsg_len = cmlen;

	if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
		return -EFAULT;
	if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
		return -EFAULT;
	cmlen = CMSG_COMPAT_SPACE(len);
	if (kmsg->msg_controllen < cmlen)
		cmlen = kmsg->msg_controllen;
	kmsg->msg_control += cmlen;
	kmsg->msg_controllen -= cmlen;
	return 0;
}

static int scm_max_fds_compat(struct msghdr *msg)
{
	if (msg->msg_controllen <= sizeof(struct compat_cmsghdr))
		return 0;
	return (msg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
}

void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm)
{
	struct compat_cmsghdr __user *cm =
		(struct compat_cmsghdr __user *)msg->msg_control;
	unsigned int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0;
	int fdmax = min_t(int, scm_max_fds_compat(msg), scm->fp->count);
	int __user *cmsg_data = CMSG_COMPAT_DATA(cm);
	int err = 0, i;

	for (i = 0; i < fdmax; i++) {
		err = receive_fd_user(scm->fp->fp[i], cmsg_data + i, o_flags);
		if (err < 0)
			break;
	}

	if (i > 0) {
		int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));

		err = put_user(SOL_SOCKET, &cm->cmsg_level);
		if (!err)
			err = put_user(SCM_RIGHTS, &cm->cmsg_type);
		if (!err)
			err = put_user(cmlen, &cm->cmsg_len);
		if (!err) {
			cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
			if (msg->msg_controllen < cmlen)
				cmlen = msg->msg_controllen;
			msg->msg_control += cmlen;
			msg->msg_controllen -= cmlen;
		}
	}

	if (i < scm->fp->count || (scm->fp->count && fdmax <= 0))
		msg->msg_flags |= MSG_CTRUNC;

	/*
	 * All of the files that fit in the message have had their usage counts
	 * incremented, so we just free the list.
	 */
	__scm_destroy(scm);
}

/* Argument list sizes for compat_sys_socketcall */
#define AL(x) ((x) * sizeof(u32))
static unsigned char nas[21] = {
	AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
	AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
	AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
	AL(4), AL(5), AL(4)
};
#undef AL

static inline long __compat_sys_sendmsg(int fd,
					struct compat_msghdr __user *msg,
					unsigned int flags)
{
	return __sys_sendmsg(fd, (struct user_msghdr __user *)msg,
			     flags | MSG_CMSG_COMPAT, false);
}

COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg,
		       unsigned int, flags)
{
	return __compat_sys_sendmsg(fd, msg, flags);
}

static inline long __compat_sys_sendmmsg(int fd,
					 struct compat_mmsghdr __user *mmsg,
					 unsigned int vlen, unsigned int flags)
{
	return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
			      flags | MSG_CMSG_COMPAT, false);
}

COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg,
		       unsigned int, vlen, unsigned int, flags)
{
	return __compat_sys_sendmmsg(fd, mmsg, vlen, flags);
}

static inline long __compat_sys_recvmsg(int fd,
					struct compat_msghdr __user *msg,
					unsigned int flags)
{
	return __sys_recvmsg(fd, (struct user_msghdr __user *)msg,
			     flags | MSG_CMSG_COMPAT, false);
}

COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg,
		       unsigned int, flags)
{
	return __compat_sys_recvmsg(fd, msg, flags);
}

static inline long __compat_sys_recvfrom(int fd, void __user *buf,
					 compat_size_t len, unsigned int flags,
					 struct sockaddr __user *addr,
					 int __user *addrlen)
{
	return __sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr,
			      addrlen);
}

COMPAT_SYSCALL_DEFINE4(recv, int, fd, void __user *, buf, compat_size_t, len, unsigned int, flags)
{
	return __compat_sys_recvfrom(fd, buf, len, flags, NULL, NULL);
}

COMPAT_SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, buf, compat_size_t, len,
		       unsigned int, flags, struct sockaddr __user *, addr,
		       int __user *, addrlen)
{
	return __compat_sys_recvfrom(fd, buf, len, flags, addr, addrlen);
}

COMPAT_SYSCALL_DEFINE5(recvmmsg_time64, int, fd, struct compat_mmsghdr __user *, mmsg,
		       unsigned int, vlen, unsigned int, flags,
		       struct __kernel_timespec __user *, timeout)
{
	return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
			      flags | MSG_CMSG_COMPAT, timeout, NULL);
}

#ifdef CONFIG_COMPAT_32BIT_TIME
COMPAT_SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct compat_mmsghdr __user *, mmsg,
		       unsigned int, vlen, unsigned int, flags,
		       struct old_timespec32 __user *, timeout)
{
	return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
			      flags | MSG_CMSG_COMPAT, NULL, timeout);
}
#endif

COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
{
	u32 a[AUDITSC_ARGS];
	unsigned int len;
	u32 a0, a1;
	int ret;

	if (call < SYS_SOCKET || call > SYS_SENDMMSG)
		return -EINVAL;
	len = nas[call];
	if (len > sizeof(a))
		return -EINVAL;

	if (copy_from_user(a, args, len))
		return -EFAULT;

	ret = audit_socketcall_compat(len / sizeof(a[0]), a);
	if (ret)
		return ret;

	a0 = a[0];
	a1 = a[1];

	switch (call) {
	case SYS_SOCKET:
		ret = __sys_socket(a0, a1, a[2]);
		break;
	case SYS_BIND:
		ret = __sys_bind(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_CONNECT:
		ret = __sys_connect(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_LISTEN:
		ret = __sys_listen(a0, a1);
		break;
	case SYS_ACCEPT:
		ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0);
		break;
	case SYS_GETSOCKNAME:
		ret = __sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
		break;
	case SYS_GETPEERNAME:
		ret = __sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
		break;
	case SYS_SOCKETPAIR:
		ret = __sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
		break;
	case SYS_SEND:
		ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3], NULL, 0);
		break;
	case SYS_SENDTO:
		ret = __sys_sendto(a0, compat_ptr(a1), a[2], a[3],
				   compat_ptr(a[4]), a[5]);
		break;
	case SYS_RECV:
		ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
					    NULL, NULL);
		break;
	case SYS_RECVFROM:
		ret = __compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
					    compat_ptr(a[4]),
					    compat_ptr(a[5]));
		break;
	case SYS_SHUTDOWN:
		ret = __sys_shutdown(a0, a1);
		break;
	case SYS_SETSOCKOPT:
		ret = __sys_setsockopt(a0, a1, a[2], compat_ptr(a[3]), a[4]);
		break;
	case SYS_GETSOCKOPT:
		ret = __sys_getsockopt(a0, a1, a[2], compat_ptr(a[3]),
				       compat_ptr(a[4]));
		break;
	case SYS_SENDMSG:
		ret = __compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_SENDMMSG:
		ret = __compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]);
		break;
	case SYS_RECVMSG:
		ret = __compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_RECVMMSG:
		ret = __sys_recvmmsg(a0, compat_ptr(a1), a[2],
				     a[3] | MSG_CMSG_COMPAT, NULL,
				     compat_ptr(a[4]));
		break;
	case SYS_ACCEPT4:
		ret = __sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
