Skip to content

Commit adc3f55

Browse files
committed
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
2 parents 318adf8 + 1e29ab3 commit adc3f55

File tree

6 files changed

+56
-30
lines changed

6 files changed

+56
-30
lines changed

arch/arm64/include/asm/syscall.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <linux/compat.h>
2121
#include <linux/err.h>
2222

23-
typedef long (*syscall_fn_t)(struct pt_regs *regs);
23+
typedef long (*syscall_fn_t)(const struct pt_regs *regs);
2424

2525
extern const syscall_fn_t sys_call_table[];
2626

arch/arm64/include/asm/syscall_wrapper.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
} \
3131
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
3232

33-
#define COMPAT_SYSCALL_DEFINE0(sname) \
34-
asmlinkage long __arm64_compat_sys_##sname(void); \
35-
ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO); \
36-
asmlinkage long __arm64_compat_sys_##sname(void)
33+
#define COMPAT_SYSCALL_DEFINE0(sname) \
34+
asmlinkage long __arm64_compat_sys_##sname(const struct pt_regs *__unused); \
35+
ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO); \
36+
asmlinkage long __arm64_compat_sys_##sname(const struct pt_regs *__unused)
3737

3838
#define COND_SYSCALL_COMPAT(name) \
3939
cond_syscall(__arm64_compat_sys_##name);
@@ -62,11 +62,11 @@
6262
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
6363

6464
#ifndef SYSCALL_DEFINE0
65-
#define SYSCALL_DEFINE0(sname) \
66-
SYSCALL_METADATA(_##sname, 0); \
67-
asmlinkage long __arm64_sys_##sname(void); \
68-
ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO); \
69-
asmlinkage long __arm64_sys_##sname(void)
65+
#define SYSCALL_DEFINE0(sname) \
66+
SYSCALL_METADATA(_##sname, 0); \
67+
asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused); \
68+
ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO); \
69+
asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused)
7070
#endif
7171

7272
#ifndef COND_SYSCALL

arch/arm64/kernel/module.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
9898

9999
/*
100100
* The ELF psABI for AArch64 documents the 16-bit and 32-bit place
101-
* relative relocations as having a range of [-2^15, 2^16) or
102-
* [-2^31, 2^32), respectively. However, in order to be able to detect
103-
* overflows reliably, we have to choose whether we interpret such
104-
* quantities as signed or as unsigned, and stick with it.
101+
* relative and absolute relocations as having a range of [-2^15, 2^16)
102+
* or [-2^31, 2^32), respectively. However, in order to be able to
103+
* detect overflows reliably, we have to choose whether we interpret
104+
* such quantities as signed or as unsigned, and stick with it.
105105
* The way we organize our address space requires a signed
106106
* interpretation of 32-bit relative references, so let's use that
107107
* 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)
111111
switch (len) {
112112
case 16:
113113
*(s16 *)place = sval;
114-
if (sval < S16_MIN || sval > S16_MAX)
115-
return -ERANGE;
114+
switch (op) {
115+
case RELOC_OP_ABS:
116+
if (sval < 0 || sval > U16_MAX)
117+
return -ERANGE;
118+
break;
119+
case RELOC_OP_PREL:
120+
if (sval < S16_MIN || sval > S16_MAX)
121+
return -ERANGE;
122+
break;
123+
default:
124+
pr_err("Invalid 16-bit data relocation (%d)\n", op);
125+
return 0;
126+
}
116127
break;
117128
case 32:
118129
*(s32 *)place = sval;
119-
if (sval < S32_MIN || sval > S32_MAX)
120-
return -ERANGE;
130+
switch (op) {
131+
case RELOC_OP_ABS:
132+
if (sval < 0 || sval > U32_MAX)
133+
return -ERANGE;
134+
break;
135+
case RELOC_OP_PREL:
136+
if (sval < S32_MIN || sval > S32_MAX)
137+
return -ERANGE;
138+
break;
139+
default:
140+
pr_err("Invalid 32-bit data relocation (%d)\n", op);
141+
return 0;
142+
}
121143
break;
122144
case 64:
123145
*(s64 *)place = sval;

arch/arm64/kernel/sys.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,26 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
4747
return ksys_personality(personality);
4848
}
4949

50+
asmlinkage long sys_ni_syscall(void);
51+
52+
asmlinkage long __arm64_sys_ni_syscall(const struct pt_regs *__unused)
53+
{
54+
return sys_ni_syscall();
55+
}
56+
5057
/*
5158
* Wrappers to pass the pt_regs argument.
5259
*/
53-
#define sys_personality sys_arm64_personality
54-
55-
asmlinkage long sys_ni_syscall(const struct pt_regs *);
56-
#define __arm64_sys_ni_syscall sys_ni_syscall
60+
#define __arm64_sys_personality __arm64_sys_arm64_personality
5761

5862
#undef __SYSCALL
5963
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
6064
#include <asm/unistd.h>
6165

6266
#undef __SYSCALL
63-
#define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)__arm64_##sym,
67+
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
6468

6569
const syscall_fn_t sys_call_table[__NR_syscalls] = {
66-
[0 ... __NR_syscalls - 1] = (syscall_fn_t)sys_ni_syscall,
70+
[0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,
6771
#include <asm/unistd.h>
6872
};

arch/arm64/kernel/sys32.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,14 @@ COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
133133
return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
134134
}
135135

136-
asmlinkage long sys_ni_syscall(const struct pt_regs *);
137-
#define __arm64_sys_ni_syscall sys_ni_syscall
138-
139136
#undef __SYSCALL
140137
#define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *);
141138
#include <asm/unistd32.h>
142139

143140
#undef __SYSCALL
144-
#define __SYSCALL(nr, sym) [nr] = (syscall_fn_t)__arm64_##sym,
141+
#define __SYSCALL(nr, sym) [nr] = __arm64_##sym,
145142

146143
const syscall_fn_t compat_sys_call_table[__NR_compat_syscalls] = {
147-
[0 ... __NR_compat_syscalls - 1] = (syscall_fn_t)sys_ni_syscall,
144+
[0 ... __NR_compat_syscalls - 1] = __arm64_sys_ni_syscall,
148145
#include <asm/unistd32.h>
149146
};

arch/arm64/kernel/traps.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,10 @@ void arm64_force_sig_fault(int signo, int code, void __user *addr,
252252
const char *str)
253253
{
254254
arm64_show_signal(signo, str);
255-
force_sig_fault(signo, code, addr, current);
255+
if (signo == SIGKILL)
256+
force_sig(SIGKILL, current);
257+
else
258+
force_sig_fault(signo, code, addr, current);
256259
}
257260

258261
void arm64_force_sig_mceerr(int code, void __user *addr, short lsb,

0 commit comments

Comments
 (0)