aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2012-12-15 19:25:57 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-12-20 05:40:24 -0500
commit7bf9b7bef881aac820bf1f2e9951a17b09bd7e04 (patch)
tree6c74611883e16e5cd6548f9dd3278a9f2fadb1e3 /arch/arm
parentdad5451a322bb682704f3ab13a558508a83e0b93 (diff)
ARM: missing ->mmap_sem around find_vma() in swp_emulate.c
find_vma() is *not* safe when somebody else is removing vmas. Not just the return value might get bogus just as you are getting it (this instance doesn't try to dereference the resulting vma), the search itself can get buggered in rather spectacular ways. IOW, ->mmap_sem really, really is not optional here. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Cc: <stable@vger.kernel.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/swp_emulate.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index df745188f5de..ab1017bd1667 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -109,10 +109,12 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr)
109{ 109{
110 siginfo_t info; 110 siginfo_t info;
111 111
112 down_read(&current->mm->mmap_sem);
112 if (find_vma(current->mm, addr) == NULL) 113 if (find_vma(current->mm, addr) == NULL)
113 info.si_code = SEGV_MAPERR; 114 info.si_code = SEGV_MAPERR;
114 else 115 else
115 info.si_code = SEGV_ACCERR; 116 info.si_code = SEGV_ACCERR;
117 up_read(&current->mm->mmap_sem);
116 118
117 info.si_signo = SIGSEGV; 119 info.si_signo = SIGSEGV;
118 info.si_errno = 0; 120 info.si_errno = 0;