lkml.org 
[lkml]   [2021]   [Oct]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v2 3/6] mm/util: Support CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
Date
From: Xiongwei Song <sxwjean@gmail.com>

With CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES enabled, archs can support 64bit
process invoke 32bit syscall via compatible mmap(), which uses
mmap_compat_base and mmap_compat_legacy_base of mm_struct, which only
x86 uses so far.

Here we assume other archs will support CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
as well.

Signed-off-by: Xiongwei Song <sxwjean@gmail.com>
---
arch/x86/include/asm/processor.h | 4 ++++
mm/util.c | 21 +++++++++++++++++++--
2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 577f342dbfb2..fb7a4f21d412 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -787,6 +787,10 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
#define __TASK_UNMAPPED_BASE(task_size) (PAGE_ALIGN(task_size / 3))
#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE_LOW)

+#ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
+#define TASK_UNMAPPED_COMPAT_BASE __TASK_UNMAPPED_BASE(task_size_32bit())
+#endif
+
#define KSTK_EIP(task) (task_pt_regs(task)->ip)

/* Get/set a process' ability to use the timestamp counter instruction */
diff --git a/mm/util.c b/mm/util.c
index 38326ef21a3b..ab3711c445e6 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -357,8 +357,9 @@ unsigned long arch_mmap_rnd(void)
{
unsigned long rnd;

-#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS
- if (is_compat_task())
+#if defined(CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS) \
+ || defined(CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES)
+ if (is_compat_task() || in_compat_syscall())
rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
else
#endif /* CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS */
@@ -422,6 +423,22 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
mm->mmap_base = mmap_base(random_factor, STACK_TOP, rlim_stack);
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
}
+#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.
+ */
+ if (mmap_is_legacy(rlim_stack)) {
+ mm->mmap_compat_legacy_base =
+ TASK_UNMAPPED_COMPAT_BASE + random_factor;
+ mm->mmap_compat_base = mm->mmap_compat_legacy_base;
+ } else {
+ mm->mmap_compat_base = mmap_base(random_factor,
+ task_size_32bit(), rlim_stack);
+ }
+#endif
}
#elif defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
--
2.30.2
\
 
 \ /
  Last update: 2021-10-11 16:35    [W:0.144 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site