// SPDX-License-Identifier: GPL-2.0
#include <linux/compat.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>

/*
 * The compat_siginfo_t structure and handing code is very easy
 * to break in several ways.  It must always be updated when new
 * updates are made to the main siginfo_t, and
 * copy_siginfo_to_user32() must be updated when the
 * (arch-independent) copy_siginfo_to_user() is updated.
 *
 * It is also easy to put a new member in the compat_siginfo_t
 * which has implicit alignment which can move internal structure
 * alignment around breaking the ABI.  This can happen if you,
 * for instance, put a plain 64-bit value in there.
 */
static inline void signal_compat_build_tests(void)
{
	int _sifields_offset = offsetof(compat_siginfo_t, _sifields);

	/*
	 * If adding a new si_code, there is probably new data in
	 * the siginfo.  Make sure folks bumping the si_code
	 * limits also have to look at this code.  Make sure any
	 * new fields are handled in copy_siginfo_to_user32()!
	 */
	BUILD_BUG_ON(NSIGILL  != 11);
	BUILD_BUG_ON(NSIGFPE  != 15);
	BUILD_BUG_ON(NSIGSEGV != 9);
	BUILD_BUG_ON(NSIGBUS  != 5);
	BUILD_BUG_ON(NSIGTRAP != 6);
	BUILD_BUG_ON(NSIGCHLD != 6);
	BUILD_BUG_ON(NSIGSYS  != 2);

	/* This is part of the ABI and can never change in size: */
	BUILD_BUG_ON(sizeof(siginfo_t) != 128);
	BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);

	/* This is a part of the ABI and can never change in alignment */
	BUILD_BUG_ON(__alignof__(siginfo_t) != 8);
	BUILD_BUG_ON(__alignof__(compat_siginfo_t) != 4);

	/*
	 * The offsets of all the (unioned) si_fields are fixed
	 * in the ABI, of course.  Make sure none of them ever
	 * move and are always at the beginning:
	 */
	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int));
#define CHECK_CSI_OFFSET(name)	  BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name))

	BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
	BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
	BUILD_BUG_ON(offsetof(siginfo_t, si_code)  != 8);

	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code)  != 8);
	 /*
	 * Ensure that the size of each si_field never changes.
	 * If it does, it is a sign that the
	 * copy_siginfo_to_user32() code below needs to updated
	 * along with the size in the CHECK_SI_SIZE().
	 *
	 * We repeat this check for both the generic and compat
	 * siginfos.
	 *
	 * Note: it is OK for these to grow as long as the whole
	 * structure stays within the padding size (checked
	 * above).
	 */
#define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name))
#define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name))

	CHECK_CSI_OFFSET(_kill);
	CHECK_CSI_SIZE  (_kill, 2*sizeof(int));
	CHECK_SI_SIZE   (_kill, 2*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);

	CHECK_CSI_OFFSET(_timer);
	CHECK_CSI_SIZE  (_timer, 3*sizeof(int));
	CHECK_SI_SIZE   (_timer, 6*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_tid)     != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14);
	BUILD_BUG_ON(offsetof(siginfo_t, si_value)   != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid)     != 0x0C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value)   != 0x14);

	CHECK_CSI_OFFSET(_rt);
	CHECK_CSI_SIZE  (_rt, 3*sizeof(int));
	CHECK_SI_SIZE   (_rt, 4*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)   != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)   != 0x14);
	BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)   != 0x0C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)   != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);

	CHECK_CSI_OFFSET(_sigchld);
	CHECK_CSI_SIZE  (_sigchld, 5*sizeof(int));
	CHECK_SI_SIZE   (_sigchld, 8*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)    != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)    != 0x14);
	BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18);
	BUILD_BUG_ON(offsetof(siginfo_t, si_utime)  != 0x20);
	BUILD_BUG_ON(offsetof(siginfo_t, si_stime)  != 0x28);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)    != 0x0C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)    != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime)  != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime)  != 0x1C);

#ifdef CONFIG_X86_X32_ABI
	CHECK_CSI_OFFSET(_sigchld_x32);
	CHECK_CSI_SIZE  (_sigchld_x32, 7*sizeof(int));
	/* no _sigchld_x32 in the generic siginfo_t */
	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime)  != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime)  != 0x20);
#endif

	CHECK_CSI_OFFSET(_sigfault);
	CHECK_CSI_SIZE  (_sigfault, 4*sizeof(int));
	CHECK_SI_SIZE   (_sigfault, 8*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);

	BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10);

	BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);

	BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
	BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);

	BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);

	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20);
	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x24);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_flags) != 0x18);

	CHECK_CSI_OFFSET(_sigpoll);
	CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
	CHECK_SI_SIZE   (_sigpoll, 4*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x18);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd)   != 0x10);

	CHECK_CSI_OFFSET(_sigsys);
	CHECK_CSI_SIZE  (_sigsys, 3*sizeof(int));
	CHECK_SI_SIZE   (_sigsys, 4*sizeof(int));

	BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
	BUILD_BUG_ON(offsetof(siginfo_t, si_syscall)   != 0x18);
	BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x1C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall)   != 0x10);
	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x14);

	/* any new si_fields should be added here */
}

void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
{
	signal_compat_build_tests();

	if (!act)
		return;

	if (in_ia32_syscall())
		act->sa.sa_flags |= SA_IA32_ABI;
	if (in_x32_syscall())
		act->sa.sa_flags |= SA_X32_ABI;
}
