]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: ensure DTrace can use get_user_pages safely
authorKris Van Hees <kris.van.hees@oracle.com>
Mon, 27 Feb 2017 15:39:07 +0000 (10:39 -0500)
committerKris Van Hees <kris.van.hees@oracle.com>
Wed, 8 Mar 2017 20:21:22 +0000 (15:21 -0500)
The processing of the DTrace-specific FOLL_IMMED flag was not robust
enough.  We could still get into a situation where cond_resched() was
called (which is bad) or where the VMA area would get extended (which
is also bad).  The only code that passes this flag is DTrace support
code, and when the flag is not passed, the execution flow is not at all
affected.

Orabug: 25640153
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Chuck Anderson <chuck.anderson@oracle.com>
Reviewed-by: Nick Alcock <nick.alcock@oracle.com>
Reviewed-by: Tomas Jedlicka <tomas.jedlicka@oracle.com>
mm/gup.c

index 50f624a0d5e6866d07e1d928ba23504cbd75a187..6f937dd4e98c79f799fd20b31ff1b92c69a5e121 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -458,7 +458,12 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
                /* first iteration or cross vma bound */
                if (!vma || start >= vma->vm_end) {
-                       vma = find_extend_vma(mm, start);
+                       /* Do not extend stack in no-fault mode. */
+                       if (gup_flags & FOLL_IMMED)
+                               vma = find_vma(mm, start);
+                       else
+                               vma = find_extend_vma(mm, start);
+
                        if (!vma && in_gate_area(mm, start)) {
                                int ret;
                                ret = get_gate_page(mm, start & PAGE_MASK,
@@ -486,7 +491,8 @@ retry:
                 */
                if (unlikely(fatal_signal_pending(current)))
                        return i ? i : -ERESTARTSYS;
-               cond_resched();
+               if (likely(!(foll_flags & FOLL_IMMED)))
+                       cond_resched();
                page = follow_page_mask(vma, start, foll_flags, &page_mask);
                if (!page) {
                        int ret;