#define MIN_GAP (128*1024*1024UL)
 #define MAX_GAP ((TASK_SIZE)/6*5)
 
-static int mmap_is_legacy(void)
+static int mmap_is_legacy(struct rlimit *rlim_stack)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
                return 1;
 
-       if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+       if (rlim_stack->rlim_cur == RLIM_INFINITY)
                return 1;
 
        return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_base(unsigned long rnd)
+static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
 
        if (gap < MIN_GAP)
                gap = MIN_GAP;
        return rnd << PAGE_SHIFT;
 }
 
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = 0UL;
 
        if (current->flags & PF_RANDOMIZE)
                random_factor = arch_mmap_rnd();
 
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
                mm->get_unmapped_area = arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
        }
 }
 
 #define MIN_GAP (SZ_128M)
 #define MAX_GAP        (STACK_TOP/6*5)
 
-static int mmap_is_legacy(void)
+static int mmap_is_legacy(struct rlimit *rlim_stack)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
                return 1;
 
-       if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+       if (rlim_stack->rlim_cur == RLIM_INFINITY)
                return 1;
 
        return sysctl_legacy_va_layout;
        return rnd << PAGE_SHIFT;
 }
 
-static unsigned long mmap_base(unsigned long rnd)
+static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
        unsigned long pad = (STACK_RND_MASK << PAGE_SHIFT) + stack_guard_gap;
 
        /* Values close to RLIM_INFINITY can overflow. */
  * This function, called very early during the creation of a new process VM
  * image, sets up which VM layout function to use:
  */
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = 0UL;
 
         * Fall back to the standard layout if the personality bit is set, or
         * if the expected stack growth is unlimited:
         */
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
                mm->get_unmapped_area = arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
        }
 }
 
 #define MIN_GAP (128*1024*1024UL)
 #define MAX_GAP ((TASK_SIZE)/6*5)
 
-static int mmap_is_legacy(void)
+static int mmap_is_legacy(struct rlimit *rlim_stack)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
                return 1;
 
-       if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+       if (rlim_stack->rlim_cur == RLIM_INFINITY)
                return 1;
 
        return sysctl_legacy_va_layout;
 }
 
-static unsigned long mmap_base(unsigned long rnd)
+static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
 
        if (gap < MIN_GAP)
                gap = MIN_GAP;
        return rnd << PAGE_SHIFT;
 }
 
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = 0UL;
 
        if (current->flags & PF_RANDOMIZE)
                random_factor = arch_mmap_rnd();
 
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
                mm->get_unmapped_area = arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
        }
 }
 
  * Top of mmap area (just below the process stack).
  */
 
-static unsigned long mmap_upper_limit(void)
+/*
+ * When called from arch_get_unmapped_area(), rlim_stack will be NULL,
+ * indicating that "current" should be used instead of a passed-in
+ * value from the exec bprm as done with arch_pick_mmap_layout().
+ */
+static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
 {
        unsigned long stack_base;
 
        /* Limit stack size - see setup_arg_pages() in fs/exec.c */
-       stack_base = rlimit_max(RLIMIT_STACK);
+       stack_base = rlim_stack ? rlim_stack->rlim_max
+                               : rlimit_max(RLIMIT_STACK);
        if (stack_base > STACK_SIZE_MAX)
                stack_base = STACK_SIZE_MAX;
 
        info.flags = 0;
        info.length = len;
        info.low_limit = mm->mmap_legacy_base;
-       info.high_limit = mmap_upper_limit();
+       info.high_limit = mmap_upper_limit(NULL);
        info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
        info.align_offset = shared_align_offset(last_mmap, pgoff);
        addr = vm_unmapped_area(&info);
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
  */
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        mm->mmap_legacy_base = mmap_legacy_base();
-       mm->mmap_base = mmap_upper_limit();
+       mm->mmap_base = mmap_upper_limit(rlim_stack);
 
        if (mmap_is_legacy()) {
                mm->mmap_base = mm->mmap_legacy_base;
 
 #define MIN_GAP (128*1024*1024)
 #define MAX_GAP (TASK_SIZE/6*5)
 
-static inline int mmap_is_legacy(void)
+static inline int mmap_is_legacy(struct rlimit *rlim_stack)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
                return 1;
 
-       if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+       if (rlim_stack->rlim_cur == RLIM_INFINITY)
                return 1;
 
        return sysctl_legacy_va_layout;
                return (1<<30);
 }
 
-static inline unsigned long mmap_base(unsigned long rnd)
+static inline unsigned long mmap_base(unsigned long rnd,
+                                     struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
        unsigned long pad = stack_maxrandom_size() + stack_guard_gap;
 
        /* Values close to RLIM_INFINITY can overflow. */
 }
 
 static void radix__arch_pick_mmap_layout(struct mm_struct *mm,
-                                       unsigned long random_factor)
+                                       unsigned long random_factor,
+                                       struct rlimit *rlim_stack)
 {
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = TASK_UNMAPPED_BASE;
                mm->get_unmapped_area = radix__arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = radix__arch_get_unmapped_area_topdown;
        }
 }
 #else
 /* dummy */
 extern void radix__arch_pick_mmap_layout(struct mm_struct *mm,
-                                       unsigned long random_factor);
+                                       unsigned long random_factor,
+                                       struct rlimit *rlim_stack);
 #endif
 /*
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
  */
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = 0UL;
 
                random_factor = arch_mmap_rnd();
 
        if (radix_enabled())
-               return radix__arch_pick_mmap_layout(mm, random_factor);
+               return radix__arch_pick_mmap_layout(mm, random_factor,
+                                                   rlim_stack);
        /*
         * Fall back to the standard layout if the personality
         * bit is set, or if the expected stack growth is unlimited:
         */
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = TASK_UNMAPPED_BASE;
                mm->get_unmapped_area = arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
        }
 }
 
 #define MIN_GAP (32*1024*1024)
 #define MAX_GAP (STACK_TOP/6*5)
 
-static inline int mmap_is_legacy(void)
+static inline int mmap_is_legacy(struct rlimit *rlim_stack)
 {
        if (current->personality & ADDR_COMPAT_LAYOUT)
                return 1;
-       if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+       if (rlim_stack->rlim_cur == RLIM_INFINITY)
                return 1;
        return sysctl_legacy_va_layout;
 }
        return TASK_UNMAPPED_BASE + rnd;
 }
 
-static inline unsigned long mmap_base(unsigned long rnd)
+static inline unsigned long mmap_base(unsigned long rnd,
+                                     struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
 
        if (gap < MIN_GAP)
                gap = MIN_GAP;
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
  */
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = 0UL;
 
         * Fall back to the standard layout if the personality
         * bit is set, or if the expected stack growth is unlimited:
         */
-       if (mmap_is_legacy()) {
+       if (mmap_is_legacy(rlim_stack)) {
                mm->mmap_base = mmap_base_legacy(random_factor);
                mm->get_unmapped_area = arch_get_unmapped_area;
        } else {
-               mm->mmap_base = mmap_base(random_factor);
+               mm->mmap_base = mmap_base(random_factor, rlim_stack);
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
        }
 }
 
        return rnd << PAGE_SHIFT;
 }
 
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        unsigned long random_factor = mmap_rnd();
        unsigned long gap;
         * Fall back to the standard layout if the personality
         * bit is set, or if the expected stack growth is unlimited:
         */
-       gap = rlimit(RLIMIT_STACK);
+       gap = rlim_stack->rlim_cur;
        if (!test_thread_flag(TIF_32BIT) ||
            (current->personality & ADDR_COMPAT_LAYOUT) ||
            gap == RLIM_INFINITY ||
 
        return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
 }
 
-static unsigned long mmap_base(unsigned long rnd, unsigned long task_size)
+static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
+                              struct rlimit *rlim_stack)
 {
-       unsigned long gap = rlimit(RLIMIT_STACK);
+       unsigned long gap = rlim_stack->rlim_cur;
        unsigned long pad = stack_maxrandom_size(task_size) + stack_guard_gap;
        unsigned long gap_min, gap_max;
 
  * process VM image, sets up which VM layout function to use:
  */
 static void arch_pick_mmap_base(unsigned long *base, unsigned long *legacy_base,
-               unsigned long random_factor, unsigned long task_size)
+               unsigned long random_factor, unsigned long task_size,
+               struct rlimit *rlim_stack)
 {
        *legacy_base = mmap_legacy_base(random_factor, task_size);
        if (mmap_is_legacy())
                *base = *legacy_base;
        else
-               *base = mmap_base(random_factor, task_size);
+               *base = mmap_base(random_factor, task_size, rlim_stack);
 }
 
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        if (mmap_is_legacy())
                mm->get_unmapped_area = arch_get_unmapped_area;
                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
 
        arch_pick_mmap_base(&mm->mmap_base, &mm->mmap_legacy_base,
-                       arch_rnd(mmap64_rnd_bits), task_size_64bit(0));
+                       arch_rnd(mmap64_rnd_bits), task_size_64bit(0),
+                       rlim_stack);
 
 #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
        /*
         * mmap_base, the compat syscall uses mmap_compat_base.
         */
        arch_pick_mmap_base(&mm->mmap_compat_base, &mm->mmap_compat_legacy_base,
-                       arch_rnd(mmap32_rnd_bits), task_size_32bit());
+                       arch_rnd(mmap32_rnd_bits), task_size_32bit(),
+                       rlim_stack);
 #endif
 }
 
 
 
 void setup_new_exec(struct linux_binprm * bprm)
 {
+       struct rlimit rlim_stack;
+
        /*
         * Once here, prepare_binrpm() will not be called any more, so
         * the final state of setuid/setgid/fscaps can be merged into the
                        current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM;
        }
 
-       arch_pick_mmap_layout(current->mm);
+       task_lock(current->group_leader);
+       rlim_stack = current->signal->rlim[RLIMIT_STACK];
+       task_unlock(current->group_leader);
+
+       arch_pick_mmap_layout(current->mm, &rlim_stack);
 
        current->sas_ss_sp = current->sas_ss_size = 0;
 
 
 #endif /* CONFIG_MEMCG */
 
 #ifdef CONFIG_MMU
-extern void arch_pick_mmap_layout(struct mm_struct *mm);
+extern void arch_pick_mmap_layout(struct mm_struct *mm,
+                                 struct rlimit *rlim_stack);
 extern unsigned long
 arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
                       unsigned long, unsigned long);
                          unsigned long len, unsigned long pgoff,
                          unsigned long flags);
 #else
-static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
+static inline void arch_pick_mmap_layout(struct mm_struct *mm,
+                                        struct rlimit *rlim_stack) {}
 #endif
 
 static inline bool in_vfork(struct task_struct *tsk)
 
 }
 
 #if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
-void arch_pick_mmap_layout(struct mm_struct *mm)
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 {
        mm->mmap_base = TASK_UNMAPPED_BASE;
        mm->get_unmapped_area = arch_get_unmapped_area;