diff options
author | Hugh Dickins <hugh@veritas.com> | 2005-08-02 00:11:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-02 00:38:00 -0400 |
commit | 690dbe1ced143876d8fa56b72310738dbe079d0a (patch) | |
tree | 4297d5647ce5e6cbe429dc506007579952c31015 | |
parent | 74f9c9c258249fba3e2e78f70691528426a6c010 (diff) |
[PATCH] x86_64: access of some bad address
x86_64 has a large sparse gate area between VSYSCALL_START and
VSYSCALL_END, not all of it presently backed by pmds. Alexander Nyberg has
found that in some circumstances gdb may try to ptrace here, and hit
get_user_pages BUG_ON. It seems odd that gdb should be accessing here, but
it certainly shouldn't crash in this way: relax BUG_ON to -EFAULT. Fixes
kernel bugzilla #4801.
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | mm/memory.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index 4e1c673784db..2405289dfdf8 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -910,9 +910,13 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
910 | pud = pud_offset(pgd, pg); | 910 | pud = pud_offset(pgd, pg); |
911 | BUG_ON(pud_none(*pud)); | 911 | BUG_ON(pud_none(*pud)); |
912 | pmd = pmd_offset(pud, pg); | 912 | pmd = pmd_offset(pud, pg); |
913 | BUG_ON(pmd_none(*pmd)); | 913 | if (pmd_none(*pmd)) |
914 | return i ? : -EFAULT; | ||
914 | pte = pte_offset_map(pmd, pg); | 915 | pte = pte_offset_map(pmd, pg); |
915 | BUG_ON(pte_none(*pte)); | 916 | if (pte_none(*pte)) { |
917 | pte_unmap(pte); | ||
918 | return i ? : -EFAULT; | ||
919 | } | ||
916 | if (pages) { | 920 | if (pages) { |
917 | pages[i] = pte_page(*pte); | 921 | pages[i] = pte_page(*pte); |
918 | get_page(pages[i]); | 922 | get_page(pages[i]); |