aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/mmap.c')
-rw-r--r--arch/x86/mm/mmap.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 1e9cb945dca1..529ab79800af 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -36,11 +36,16 @@ struct va_alignment __read_mostly va_align = {
.flags = -1,
};
-static inline unsigned long tasksize_32bit(void)
+unsigned long tasksize_32bit(void)
{
return IA32_PAGE_OFFSET;
}
+unsigned long tasksize_64bit(void)
+{
+ return TASK_SIZE_MAX;
+}
+
static unsigned long stack_maxrandom_size(unsigned long task_size)
{
unsigned long max = 0;
@@ -81,6 +86,8 @@ static unsigned long arch_rnd(unsigned int rndbits)
unsigned long arch_mmap_rnd(void)
{
+ if (!(current->flags & PF_RANDOMIZE))
+ return 0;
return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
}
@@ -114,22 +121,36 @@ static unsigned long mmap_legacy_base(unsigned long rnd,
* 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)
+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 = 0UL;
-
- if (current->flags & PF_RANDOMIZE)
- random_factor = arch_mmap_rnd();
-
- mm->mmap_legacy_base = mmap_legacy_base(random_factor, TASK_SIZE);
+ *legacy_base = mmap_legacy_base(random_factor, task_size);
+ if (mmap_is_legacy())
+ *base = *legacy_base;
+ else
+ *base = mmap_base(random_factor, task_size);
+}
- if (mmap_is_legacy()) {
- mm->mmap_base = mm->mmap_legacy_base;
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+ if (mmap_is_legacy())
mm->get_unmapped_area = arch_get_unmapped_area;
- } else {
- mm->mmap_base = mmap_base(random_factor, TASK_SIZE);
+ else
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), tasksize_64bit());
+
+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+ /*
+ * The mmap syscall mapping base decision depends solely on the
+ * syscall type (64-bit or compat). This applies for 64bit
+ * applications and 32bit applications. The 64bit syscall uses
+ * 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), tasksize_32bit());
+#endif
}
const char *arch_vma_name(struct vm_area_struct *vma)