summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2019-07-11 20:57:43 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-31 07:24:53 +0200
commit0ebe6d4221a190ae56ca547715707f96851b4772 (patch)
treed57b8a8aff91d499a6ede05a4d68afad1c26db07 /mm
parentffd51eba9112438382acd9850a2bc3f29bb57b65 (diff)
downloadlinux-stable-0ebe6d4221a190ae56ca547715707f96851b4772.tar.gz
linux-stable-0ebe6d4221a190ae56ca547715707f96851b4772.tar.bz2
linux-stable-0ebe6d4221a190ae56ca547715707f96851b4772.zip
mm/gup.c: remove some BUG_ONs from get_gate_page()
[ Upstream commit b5d1c39f34d1c9bca0c4b9ae2e339fbbe264a9c7 ] If we end up without a PGD or PUD entry backing the gate area, don't BUG -- just fail gracefully. It's not entirely implausible that this could happen some day on x86. It doesn't right now even with an execute-only emulated vsyscall page because the fixmap shares the PUD, but the core mm code shouldn't rely on that particular detail to avoid OOPSing. Link: http://lkml.kernel.org/r/a1d9f4efb75b9d464e59fd6af00104b21c58f6f7.1561610798.git.luto@kernel.org Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Florian Weimer <fweimer@redhat.com> Cc: Jann Horn <jannh@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/gup.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/mm/gup.c b/mm/gup.c
index 22855ff0b448..d2c14fc4b5d4 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -585,11 +585,14 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
pgd = pgd_offset_k(address);
else
pgd = pgd_offset_gate(mm, address);
- BUG_ON(pgd_none(*pgd));
+ if (pgd_none(*pgd))
+ return -EFAULT;
p4d = p4d_offset(pgd, address);
- BUG_ON(p4d_none(*p4d));
+ if (p4d_none(*p4d))
+ return -EFAULT;
pud = pud_offset(p4d, address);
- BUG_ON(pud_none(*pud));
+ if (pud_none(*pud))
+ return -EFAULT;
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
return -EFAULT;