Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adc3f554 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 318adf8e 1e29ab31
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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[];

+9 −9
Original line number Diff line number Diff line
@@ -31,9 +31,9 @@
	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);		\
	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(void)
	asmlinkage long __arm64_compat_sys_##sname(const struct pt_regs *__unused)

#define COND_SYSCALL_COMPAT(name) \
	cond_syscall(__arm64_compat_sys_##name);
@@ -64,9 +64,9 @@
#ifndef SYSCALL_DEFINE0
#define SYSCALL_DEFINE0(sname)							\
	SYSCALL_METADATA(_##sname, 0);						\
	asmlinkage long __arm64_sys_##sname(void);		\
	asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused);	\
	ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO);			\
	asmlinkage long __arm64_sys_##sname(void)
	asmlinkage long __arm64_sys_##sname(const struct pt_regs *__unused)
#endif

#ifndef COND_SYSCALL
+30 −8
Original line number Diff line number Diff line
@@ -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,14 +111,36 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
	switch (len) {
	case 16:
		*(s16 *)place = sval;
		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;
		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;
		break;
+10 −6
Original line number Diff line number Diff line
@@ -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>
};
+2 −5
Original line number Diff line number Diff line
@@ -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>
};
Loading