|
@@ -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)
|