diff options
Diffstat (limited to 'arch/loongarch/kernel/syscall.c')
| -rw-r--r-- | arch/loongarch/kernel/syscall.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c index 168bd97540f8..94c1c3b5b0b5 100644 --- a/arch/loongarch/kernel/syscall.c +++ b/arch/loongarch/kernel/syscall.c @@ -9,6 +9,7 @@ #include <linux/entry-common.h> #include <linux/errno.h> #include <linux/linkage.h> +#include <linux/nospec.h> #include <linux/objtool.h> #include <linux/randomize_kstack.h> #include <linux/syscalls.h> @@ -34,9 +35,22 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long, return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); } +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, + prot, unsigned long, flags, unsigned long, fd, unsigned long, offset) +{ + if (offset & (~PAGE_MASK >> 12)) + return -EINVAL; + + return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - 12)); +} + void *sys_call_table[__NR_syscalls] = { [0 ... __NR_syscalls - 1] = sys_ni_syscall, +#ifdef CONFIG_32BIT +#include <asm/syscall_table_32.h> +#else #include <asm/syscall_table_64.h> +#endif }; typedef long (*sys_call_fn)(unsigned long, unsigned long, @@ -61,21 +75,10 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs) add_random_kstack_offset(); if (nr < NR_syscalls) { - syscall_fn = sys_call_table[nr]; + syscall_fn = sys_call_table[array_index_nospec(nr, NR_syscalls)]; regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6], regs->regs[7], regs->regs[8], regs->regs[9]); } - /* - * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 - * bits. The actual entropy will be further reduced by the compiler - * when applying stack alignment constraints: 16-bytes (i.e. 4-bits) - * aligned, which will remove the 4 low bits from any entropy chosen - * here. - * - * The resulting 6 bits of entropy is seen in SP[9:4]. - */ - choose_random_kstack_offset(drdtime()); - syscall_exit_to_user_mode(regs); } |
