linux/arch/x86/kernel/signal_compat.c
Linus Torvalds 23221d997b arm64 updates for 4.17
Nothing particularly stands out here, probably because people were tied
 up with spectre/meltdown stuff last time around. Still, the main pieces
 are:
 
 - Rework of our CPU features framework so that we can whitelist CPUs that
   don't require kpti even in a heterogeneous system
 
 - Support for the IDC/DIC architecture extensions, which allow us to elide
   instruction and data cache maintenance when writing out instructions
 
 - Removal of the large memory model which resulted in suboptimal codegen
   by the compiler and increased the use of literal pools, which could
   potentially be used as ROP gadgets since they are mapped as executable
 
 - Rework of forced signal delivery so that the siginfo_t is well-formed
   and handling of show_unhandled_signals is consolidated and made
   consistent between different fault types
 
 - More siginfo cleanup based on the initial patches from Eric Biederman
 
 - Workaround for Cortex-A55 erratum #1024718
 
 - Some small ACPI IORT updates and cleanups from Lorenzo Pieralisi
 
 - Misc cleanups and non-critical fixes
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABCgAGBQJaw1TCAAoJELescNyEwWM0gyQIAJVMK4QveBW+LwF96NYdZo16
 p90Aa+nqKelh/s93govQArDMv1gxyuXdFlQZVOGPQHfqpz6RhJWmBA2tFsUbQrUc
 OBcioPrRihqTmKBe+1r1XORwZxkVX6GGmCn0LYpPR7I3TjxXZpvxqaxGxiUvHkci
 yVxWlDTyN/7eL3akhCpCDagN3Fxwk3QnJLqE3fxOFMlY7NvQcmUxcITiUl/s469q
 xK6SWH9SRH1JK8jTHPitwUBiU//3FfCqSI9HLEdDIDoTuPcVM8UetWvi4QzrzJL1
 UYg8lmU0CXNmflDzZJDaMf+qFApOrGxR0YVPpBzlQvxe0JIY69g48f+JzDPz8nc=
 =+gNa
 -----END PGP SIGNATURE-----

Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 updates from Will Deacon:
 "Nothing particularly stands out here, probably because people were
  tied up with spectre/meltdown stuff last time around. Still, the main
  pieces are:

   - Rework of our CPU features framework so that we can whitelist CPUs
     that don't require kpti even in a heterogeneous system

   - Support for the IDC/DIC architecture extensions, which allow us to
     elide instruction and data cache maintenance when writing out
     instructions

   - Removal of the large memory model which resulted in suboptimal
     codegen by the compiler and increased the use of literal pools,
     which could potentially be used as ROP gadgets since they are
     mapped as executable

   - Rework of forced signal delivery so that the siginfo_t is
     well-formed and handling of show_unhandled_signals is consolidated
     and made consistent between different fault types

   - More siginfo cleanup based on the initial patches from Eric
     Biederman

   - Workaround for Cortex-A55 erratum #1024718

   - Some small ACPI IORT updates and cleanups from Lorenzo Pieralisi

   - Misc cleanups and non-critical fixes"

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (70 commits)
  arm64: uaccess: Fix omissions from usercopy whitelist
  arm64: fpsimd: Split cpu field out from struct fpsimd_state
  arm64: tlbflush: avoid writing RES0 bits
  arm64: cmpxchg: Include linux/compiler.h in asm/cmpxchg.h
  arm64: move percpu cmpxchg implementation from cmpxchg.h to percpu.h
  arm64: cmpxchg: Include build_bug.h instead of bug.h for BUILD_BUG
  arm64: lse: Include compiler_types.h and export.h for out-of-line LL/SC
  arm64: fpsimd: include <linux/init.h> in fpsimd.h
  drivers/perf: arm_pmu_platform: do not warn about affinity on uniprocessor
  perf: arm_spe: include linux/vmalloc.h for vmap()
  Revert "arm64: Revert L1_CACHE_SHIFT back to 6 (64-byte cache line size)"
  arm64: cpufeature: Avoid warnings due to unused symbols
  arm64: Add work around for Arm Cortex-A55 Erratum 1024718
  arm64: Delay enabling hardware DBM feature
  arm64: Add MIDR encoding for Arm Cortex-A55 and Cortex-A35
  arm64: capabilities: Handle shared entries
  arm64: capabilities: Add support for checks based on a list of MIDRs
  arm64: Add helpers for checking CPU MIDR against a range
  arm64: capabilities: Clean up midr range helpers
  arm64: capabilities: Change scope of VHE to Boot CPU feature
  ...
2018-04-04 16:01:43 -07:00

183 lines
6.8 KiB
C

// 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 != 14);
BUILD_BUG_ON(NSIGSEGV != 7);
BUILD_BUG_ON(NSIGBUS != 5);
BUILD_BUG_ON(NSIGTRAP != 4);
BUILD_BUG_ON(NSIGCHLD != 6);
BUILD_BUG_ON(NSIGSYS != 1);
/* This is part of the ABI and can never change in size: */
BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);
/*
* 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_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);
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();
/* Don't leak in-kernel non-uapi flags to user-space */
if (oact)
oact->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
if (!act)
return;
/* Don't let flags to be set from userspace */
act->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
if (in_ia32_syscall())
act->sa.sa_flags |= SA_IA32_ABI;
if (in_x32_syscall())
act->sa.sa_flags |= SA_X32_ABI;
}