summaryrefslogtreecommitdiff
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorPetar Jovanovic <petar.jovanovic@rt-rk.com>2016-07-13 15:23:37 +0200
committerRalf Baechle <ralf@linux-mips.org>2016-07-21 14:27:32 +0200
commitbcfc8f0d4a0a892b04c41c928cf077502b459fcc (patch)
treee7158787c2afbdf181c384446281e02654cb2602 /arch/mips/kernel/traps.c
parent008d0cf1ec69ec6d2c08f2d23aff2b67cbe5d2af (diff)
MIPS: traps: return correct si code for accessing nonmapped addresses
find_vma() returns the first VMA which satisfies fault_addr < vm_end, but it does not guarantee fault_addr is actually within VMA. Therefore, kernel has to check that before it chooses correct si code on return. Signed-off-by: Petar Jovanovic <petar.jovanovic@rt-rk.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13808/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 4a1712b5abdf..b7b50d5caaf8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -704,6 +704,7 @@ asmlinkage void do_ov(struct pt_regs *regs)
int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
{
struct siginfo si = { 0 };
+ struct vm_area_struct *vma;
switch (sig) {
case 0:
@@ -744,7 +745,8 @@ int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
si.si_addr = fault_addr;
si.si_signo = sig;
down_read(&current->mm->mmap_sem);
- if (find_vma(current->mm, (unsigned long)fault_addr))
+ vma = find_vma(current->mm, (unsigned long)fault_addr);
+ if (vma && (vma->vm_start <= (unsigned long)fault_addr))
si.si_code = SEGV_ACCERR;
else
si.si_code = SEGV_MAPERR;