Message ID | a1d9f4efb75b9d464e59fd6af00104b21c58f6f7.1561610798.git.luto@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm/gup: Remove some BUG_ONs from get_gate_page() | expand |
On Wed, Jun 26, 2019 at 09:47:30PM -0700, Andy Lutomirski wrote: > 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. > > Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Kees Cook <keescook@chromium.org> -Kees > --- > mm/gup.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/mm/gup.c b/mm/gup.c > index ddde097cf9e4..9883b598fd6f 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; > -- > 2.21.0 >
diff --git a/mm/gup.c b/mm/gup.c index ddde097cf9e4..9883b598fd6f 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;
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. Signed-off-by: Andy Lutomirski <luto@kernel.org> --- mm/gup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)