mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
arm64 fixes for -rc3
- Fix implementation of our set_personality() system call, which wasn't being wrapped properly - Fix system call function types to keep CFI happy - Fix siginfo layout when delivering SIGKILL after a kernel fault - Really fix module relocation range checking -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEPxTL6PPUbjXGY88ct6xw3ITBYzQFAlzvv3EACgkQt6xw3ITB YzQviwf9Gw3VrBZpS9nwz0MQCf9W7+Vpy8XBsY7HJyUNQ4+8ZNR5HoZ3BcJX2HWk WKwSw721MllzLfJaRMqNV2+C7lm+EypcZApKFpPo7Vs9g78WcUdNZ4YM4XfAX45T cVPxeSGOj2aswyOn2Xa3UjKZj8deP8nAC/JgJY7t9L6qKObwUldmxBPRnZdclclw S8sQSMvLc9Q43jmEysPLixExZ6jzmq1i8xxPcyqFUz8DHYPf1irLxtpS7DYA+nk5 nwQ/lnz6Tu8TBXcvgvXayKL8aa8SIsl0cOii2FWsZMkFXz3OZ08hdujvMYsPSSHO q3rMub7F/0znm00sBGXgTGRjy++v+A== =pyp4 -----END PGP SIGNATURE----- Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux Pull arm64 fixes from Will Deacon: "The fixes are still trickling in for arm64, but the only really significant one here is actually fixing a regression in the botched module relocation range checking merged for -rc2. Hopefully we've nailed it this time. - Fix implementation of our set_personality() system call, which wasn't being wrapped properly - Fix system call function types to keep CFI happy - Fix siginfo layout when delivering SIGKILL after a kernel fault - Really fix module relocation range checking" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: use the correct function type for __arm64_sys_ni_syscall arm64: use the correct function type in SYSCALL_DEFINE0 arm64: fix syscall_fn_t type signal/arm64: Use force_sig not force_sig_fault for SIGKILL arm64/module: revert to unsigned interpretation of ABS16/32 relocations arm64: Fix the arm64_personality() syscall wrapper redirection
This commit is contained in:
commit
adc3f554fa
6 changed files with 56 additions and 30 deletions
|
@ -20,7 +20,7 @@
|
|||
#include <linux/compat.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
typedef long (*syscall_fn_t)(struct pt_regs *regs);
|
||||
typedef long (*syscall_fn_t)(const struct pt_regs *regs);
|
||||
|
||||
extern const syscall_fn_t sys_call_table[];
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
} \
|
||||
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
|
||||
#define COMPAT_SYSCALL_DEFINE0(sname) \
|
||||
asmlinkage long __arm64_compat_sys_##sname(void); \
|
||||
ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO); \
|
||||
asmlinkage long __arm64_compat_sys_##sname(void)
|
||||
#define COMPAT_SYSCALL_DEFINE0(sname) \
|
||||
asmlinkage long __arm64_compat_sys_##sname(const struct pt_regs *__unused); \
|
||||
ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO); \
|
||||
asmlinkage long __arm64_compat_sys_##sname(const struct pt_regs *__unused)
|
||||
|
||||
#define COND_SYSCALL_COMPAT(name) \
|
||||
cond_syscall(__arm64_compat_sys_##name);
|
||||
|
@ -62,11 +62,11 @@
|
|||
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
|
||||
#ifndef SYSCALL_DEFINE0
|
||||
#define SYSCALL_DEFINE0(sname) \
|
||||
SYSCALL_METADATA(_##sname, 0); \
|
||||
asmlinkage long __arm64_sys_##sname(void); \
|
||||
ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO); \
|
||||
asmlinkage long __arm64_sys_##sname(void)
|
||||
#define SYSCALL_DEFINE0(sname) \
|
||||
SYSCALL_METADATA(_##sname, 0); \
|
||||
asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused); \
|
||||
ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO); \
|
||||
asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused)
|
||||
#endif
|
||||
|
||||
#ifndef COND_SYSCALL
|
||||
|
|
|
@ -98,10 +98,10 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
|
|||
|
||||
/*
|
||||
* The ELF psABI for AArch64 documents the 16-bit and 32-bit place
|
||||
* relative relocations as having a range of [-2^15, 2^16) or
|
||||
* [-2^31, 2^32), respectively. However, in order to be able to detect
|
||||
* overflows reliably, we have to choose whether we interpret such
|
||||
* quantities as signed or as unsigned, and stick with it.
|
||||
* relative and absolute relocations as having a range of [-2^15, 2^16)
|
||||
* or [-2^31, 2^32), respectively. However, in order to be able to
|
||||
* detect overflows reliably, we have to choose whether we interpret
|
||||
* such quantities as signed or as unsigned, and stick with it.
|
||||
* The way we organize our address space requires a signed
|
||||
* interpretation of 32-bit relative references, so let's use that
|
||||
* for all R_AARCH64_PRELxx relocations. This means our upper
|
||||
|
@ -111,13 +111,35 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
|
|||
switch (len) {
|
||||
case 16:
|
||||
*(s16 *)place = sval;
|
||||
if (sval < S16_MIN || sval > S16_MAX)
|
||||
return -ERANGE;
|
||||
switch (op) {
|
||||
case RELOC_OP_ABS:
|
||||
if (sval < 0 || sval > U16_MAX)
|
||||
return -ERANGE;
|
||||
break;
|
||||
case RELOC_OP_PREL:
|
||||
if (sval < S16_MIN || sval > S16_MAX)
|
||||
return -ERANGE;
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid 16-bit data relocation (%d)\n", op);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
*(s32 *)place = sval;
|
||||
if (sval < S32_MIN || sval > S32_MAX)
|
||||
return -ERANGE;
|
||||
switch (op) {
|
||||
case RELOC_OP_ABS:
|
||||
if (sval < 0 || sval > U32_MAX)
|
||||
return -ERANGE;
|
||||
break;
|
||||
case RELOC_OP_PREL:
|
||||
if (sval < S32_MIN || sval > S32_MAX)
|
||||
return -ERANGE;
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid 32-bit data relocation (%d)\n", op);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
*(s64 *)place = sval;
|
||||
|
|
|
@ -47,22 +47,26 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
|
|||
return ksys_personality(personality);
|
||||
}
|
||||
|
||||
asmlinkage long sys_ni_syscall(void);
|
||||
|
||||
asmlinkage long __arm64_sys_ni_syscall(const struct pt_regs *__unused)
|
||||
{
|
||||
return sys_ni_syscall();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers to pass the pt_regs argument.
|
||||
*/
|
||||
#define sys_personality sys_arm64_personality
|
||||
|
||||
asmlinkage long sys_ni_syscall(const struct pt_regs *);
|
||||
#define __arm64_sys_ni_syscall sys_ni_syscall
|
||||
#define __arm64_sys_personality __arm64_sys_arm64_personality
|
||||
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
|
||||
#include <asm/unistd.h>
|
||||
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)__arm64_##sym,
|
||||
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
|
||||
|
||||
const syscall_fn_t sys_call_table[__NR_syscalls] = {
|
||||
[0 ... __NR_syscalls - 1] = (syscall_fn_t)sys_ni_syscall,
|
||||
[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,
|
||||
#include <asm/unistd.h>
|
||||
};
|
||||
|
|
|
@ -133,17 +133,14 @@ COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
|
|||
return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
|
||||
}
|
||||
|
||||
asmlinkage long sys_ni_syscall(const struct pt_regs *);
|
||||
#define __arm64_sys_ni_syscall sys_ni_syscall
|
||||
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
|
||||
#include <asm/unistd32.h>
|
||||
|
||||
#undef __SYSCALL
|
||||
#define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)__arm64_##sym,
|
||||
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
|
||||
|
||||
const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = {
|
||||
[0 ... __NR_compat_syscalls - 1] = (syscall_fn_t)sys_ni_syscall,
|
||||
[0 ... __NR_compat_syscalls - 1] = __arm64_sys_ni_syscall,
|
||||
#include <asm/unistd32.h>
|
||||
};
|
||||
|
|
|
@ -252,7 +252,10 @@ void arm64_force_sig_fault(int signo, int code, void __user *addr,
|
|||
const char *str)
|
||||
{
|
||||
arm64_show_signal(signo, str);
|
||||
force_sig_fault(signo, code, addr, current);
|
||||
if (signo == SIGKILL)
|
||||
force_sig(SIGKILL, current);
|
||||
else
|
||||
force_sig_fault(signo, code, addr, current);
|
||||
}
|
||||
|
||||
void arm64_force_sig_mceerr(int code, void __user *addr, short lsb,
|
||||
|
|
Loading…
Reference in a new issue