linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Provide generic top-down mmap layout functions
@ 2019-03-22  7:42 Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22  7:42 UTC (permalink / raw)
  To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm
  Cc: Alexandre Ghiti

This series introduces generic functions to make top-down mmap layout
easily accessible to architectures, in particular riscv which was
the initial goal of this series.
The generic implementation was taken from arm64 and used successively
by arm, mips and finally riscv.

Note that in addition the series fixes 2 issues:
- stack randomization was taken into account even if not necessary.
- [1] fixed an issue with mmap base which did not take into account
  randomization but did not report it to arm and mips, so by moving
  arm64 into a generic library, this problem is now fixed for both
  architectures.

This work is an effort to factorize architecture functions to avoid
code duplication and oversights as in [1].

[1]: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1429066.html

Alexandre Ghiti (4):
  arm64, mm: Move generic mmap layout functions to mm
  arm: Use generic mmap top-down layout
  mips: Use generic mmap top-down layout
  riscv: Make mmap allocation top-down by default

 arch/arm/include/asm/processor.h   |  2 +-
 arch/arm/mm/mmap.c                 | 52 ----------------
 arch/arm64/include/asm/processor.h |  2 +-
 arch/arm64/mm/mmap.c               | 72 ----------------------
 arch/mips/include/asm/processor.h  |  4 +-
 arch/mips/mm/mmap.c                | 57 -----------------
 arch/riscv/Kconfig                 | 12 ++++
 arch/riscv/include/asm/processor.h |  1 +
 fs/binfmt_elf.c                    | 20 ------
 include/linux/mm.h                 |  2 +
 kernel/sysctl.c                    |  6 +-
 mm/util.c                          | 99 +++++++++++++++++++++++++++++-
 12 files changed, 121 insertions(+), 208 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
  2019-03-22  7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
@ 2019-03-22  7:42 ` Alexandre Ghiti
  2019-03-22 13:21   ` Christoph Hellwig
  2019-03-22  7:42 ` [PATCH 2/4] arm: Use generic mmap top-down layout Alexandre Ghiti
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22  7:42 UTC (permalink / raw)
  To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm
  Cc: Alexandre Ghiti

arm64 handles top-down mmap layout in a way that can be easily reused
by other architectures, so make it available in mm.

This commit also takes the opportunity to:
- make use of is_compat_task instead of specific arm64 test
  test_thread_flag(TIF_32BIT), which allows more genericity and is
  equivalent.
- fix the case where stack randomization should not be taken into
  account.

It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
that can be defined by other architectures to benefit from those functions.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
 arch/arm64/include/asm/processor.h |  2 +-
 arch/arm64/mm/mmap.c               | 72 ----------------------
 fs/binfmt_elf.c                    | 20 ------
 include/linux/mm.h                 |  2 +
 kernel/sysctl.c                    |  6 +-
 mm/util.c                          | 99 +++++++++++++++++++++++++++++-
 6 files changed, 105 insertions(+), 96 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5d9ce62bdebd..2358707c31ff 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -274,7 +274,7 @@ static inline void spin_lock_prefetch(const void *ptr)
 		     "nop") : : "p" (ptr));
 }
 
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 
 #endif
 
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 842c8a5fcd53..c74224421216 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -31,78 +31,6 @@
 
 #include <asm/cputype.h>
 
-/*
- * Leave enough space between the mmap area and the stack to honour ulimit in
- * the face of randomisation.
- */
-#define MIN_GAP (SZ_128M)
-#define MAX_GAP	(STACK_TOP/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (rlim_stack->rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-unsigned long arch_mmap_rnd(void)
-{
-	unsigned long rnd;
-
-#ifdef CONFIG_COMPAT
-	if (test_thread_flag(TIF_32BIT))
-		rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
-	else
-#endif
-		rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
-	return rnd << PAGE_SHIFT;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_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. */
-	if (gap + pad > gap)
-		gap += pad;
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return PAGE_ALIGN(STACK_TOP - gap - 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, struct rlimit *rlim_stack)
-{
-	unsigned long random_factor = 0UL;
-
-	if (current->flags & PF_RANDOMIZE)
-		random_factor = arch_mmap_rnd();
-
-	/*
-	 * Fall back to the standard layout if the personality bit is set, or
-	 * if the expected stack growth is unlimited:
-	 */
-	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, rlim_stack);
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-	}
-}
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
  * away in the future.
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 7d09d125f148..045f3b29d264 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -662,26 +662,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
  * libraries.  There is no binary dependent code anywhere else.
  */
 
-#ifndef STACK_RND_MASK
-#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))	/* 8MB of VA */
-#endif
-
-static unsigned long randomize_stack_top(unsigned long stack_top)
-{
-	unsigned long random_variable = 0;
-
-	if (current->flags & PF_RANDOMIZE) {
-		random_variable = get_random_long();
-		random_variable &= STACK_RND_MASK;
-		random_variable <<= PAGE_SHIFT;
-	}
-#ifdef CONFIG_STACK_GROWSUP
-	return PAGE_ALIGN(stack_top) + random_variable;
-#else
-	return PAGE_ALIGN(stack_top) - random_variable;
-#endif
-}
-
 static int load_elf_binary(struct linux_binprm *bprm)
 {
 	struct file *interpreter = NULL; /* to shut gcc up */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 76769749b5a5..087824a5059f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2312,6 +2312,8 @@ extern int install_special_mapping(struct mm_struct *mm,
 				   unsigned long addr, unsigned long len,
 				   unsigned long flags, struct page **pages);
 
+unsigned long randomize_stack_top(unsigned long stack_top);
+
 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
 
 extern unsigned long mmap_region(struct file *file, unsigned long addr,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e5da394d1ca3..ac388f8ccbe4 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -269,7 +269,8 @@ extern struct ctl_table epoll_table[];
 extern struct ctl_table firmware_config_table[];
 #endif
 
-#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
+#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
+	defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
 int sysctl_legacy_va_layout;
 #endif
 
@@ -1564,7 +1565,8 @@ static struct ctl_table vm_table[] = {
 		.proc_handler	= proc_dointvec,
 		.extra1		= &zero,
 	},
-#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
+#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
+	defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
 	{
 		.procname	= "legacy_va_layout",
 		.data		= &sysctl_legacy_va_layout,
diff --git a/mm/util.c b/mm/util.c
index d559bde497a9..5a0d4b1e17d9 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -14,6 +14,13 @@
 #include <linux/hugetlb.h>
 #include <linux/vmalloc.h>
 #include <linux/userfaultfd_k.h>
+#include <linux/elf.h>
+#include <linux/elf-randomize.h>
+#include <linux/personality.h>
+#include <linux/random.h>
+#include <linux/processor.h>
+#include <linux/sizes.h>
+#include <linux/compat.h>
 
 #include <linux/uaccess.h>
 
@@ -291,13 +298,103 @@ int vma_is_stack_for_current(struct vm_area_struct *vma)
 	return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
 }
 
-#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
+#ifndef STACK_RND_MASK
+#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))     /* 8MB of VA */
+#endif
+
+unsigned long randomize_stack_top(unsigned long stack_top)
+{
+	unsigned long random_variable = 0;
+
+	if (current->flags & PF_RANDOMIZE) {
+		random_variable = get_random_long();
+		random_variable &= STACK_RND_MASK;
+		random_variable <<= PAGE_SHIFT;
+	}
+#ifdef CONFIG_STACK_GROWSUP
+	return PAGE_ALIGN(stack_top) + random_variable;
+#else
+	return PAGE_ALIGN(stack_top) - random_variable;
+#endif
+}
+
+#ifdef CONFIG_MMU
+#ifdef ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
+
+#ifdef CONFIG_ARCH_HAS_ELF_RANDOMIZE
+unsigned long arch_mmap_rnd(void)
+{
+	unsigned long rnd;
+
+#ifdef CONFIG_COMPAT
+	if (is_compat_task())
+		rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
+	else
+#endif
+		rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
+
+	return rnd << PAGE_SHIFT;
+}
+#endif
+
+static int mmap_is_legacy(struct rlimit *rlim_stack)
+{
+	if (current->personality & ADDR_COMPAT_LAYOUT)
+		return 1;
+
+	if (rlim_stack->rlim_cur == RLIM_INFINITY)
+		return 1;
+
+	return sysctl_legacy_va_layout;
+}
+
+#define MIN_GAP		(SZ_128M)
+#define MAX_GAP		(STACK_TOP / 6 * 5)
+
+static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
+{
+	unsigned long gap = rlim_stack->rlim_cur;
+	unsigned long pad = stack_guard_gap;
+
+	/* Account for stack randomization if necessary */
+	if (current->flags & PF_RANDOMIZE)
+		pad += (STACK_RND_MASK << PAGE_SHIFT);
+
+	/* Values close to RLIM_INFINITY can overflow. */
+	if (gap + pad > gap)
+		gap += pad;
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return PAGE_ALIGN(STACK_TOP - gap - rnd);
+}
+
+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(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, rlim_stack);
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+	}
+}
+#elif !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
 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;
 }
 #endif
+#endif /* CONFIG_MMU */
 
 /*
  * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] arm: Use generic mmap top-down layout
  2019-03-22  7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
@ 2019-03-22  7:42 ` Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 3/4] mips: " Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
  3 siblings, 0 replies; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22  7:42 UTC (permalink / raw)
  To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm
  Cc: Alexandre Ghiti

arm uses a top-down layout by default that fits the generic functions.
At the same time, this commit allows to fix the following problems:

- one uncovered and not fixed for arm here:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1429066.html

- the use of TASK_SIZE instead of STACK_TOP in mmap_base which, when
  address space of a task is 26 bits, would assign mmap base way too high.

Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
 arch/arm/include/asm/processor.h |  2 +-
 arch/arm/mm/mmap.c               | 52 --------------------------------
 2 files changed, 1 insertion(+), 53 deletions(-)

diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 57fe73ea0f72..03837d325a2f 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -143,7 +143,7 @@ static inline void prefetchw(const void *ptr)
 #endif
 #endif
 
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 
 #endif
 
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index f866870db749..b8d912ac9e61 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -17,33 +17,6 @@
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
-/* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (rlim_stack->rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
-{
-	unsigned long gap = rlim_stack->rlim_cur;
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return PAGE_ALIGN(TASK_SIZE - gap - rnd);
-}
-
 /*
  * We need to ensure that shared mappings are correctly aligned to
  * avoid aliasing issues with VIPT caches.  We need to ensure that
@@ -171,31 +144,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 	return addr;
 }
 
-unsigned long arch_mmap_rnd(void)
-{
-	unsigned long rnd;
-
-	rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
-
-	return rnd << PAGE_SHIFT;
-}
-
-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(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, rlim_stack);
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-	}
-}
-
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This
  * might go away in the future.
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] mips: Use generic mmap top-down layout
  2019-03-22  7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 2/4] arm: Use generic mmap top-down layout Alexandre Ghiti
@ 2019-03-22  7:42 ` Alexandre Ghiti
  2019-03-22  7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
  3 siblings, 0 replies; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22  7:42 UTC (permalink / raw)
  To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm
  Cc: Alexandre Ghiti

mips uses a top-down layout by default that fits the generic functions.
At the same time, this commit allows to fix problem uncovered
and not fixed for mips here:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1429066.html

Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
 arch/mips/include/asm/processor.h |  4 +--
 arch/mips/mm/mmap.c               | 57 -------------------------------
 2 files changed, 2 insertions(+), 59 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index aca909bd7841..f8e04962b52d 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -30,9 +30,9 @@
 extern unsigned int vced_count, vcei_count;
 
 /*
- * MIPS does have an arch_pick_mmap_layout()
+ * MIPS uses the default implementation of topdown mmap layout.
  */
-#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 
 #ifdef CONFIG_32BIT
 #ifdef CONFIG_KVM_GUEST
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 2f616ebeb7e0..61e65a69bb09 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -20,33 +20,6 @@
 unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
 EXPORT_SYMBOL(shm_align_mask);
 
-/* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (rlim_stack->rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
-{
-	unsigned long gap = rlim_stack->rlim_cur;
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return PAGE_ALIGN(TASK_SIZE - gap - rnd);
-}
-
 #define COLOUR_ALIGN(addr, pgoff)				\
 	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
 	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
@@ -144,36 +117,6 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 			addr0, len, pgoff, flags, DOWN);
 }
 
-unsigned long arch_mmap_rnd(void)
-{
-	unsigned long rnd;
-
-#ifdef CONFIG_COMPAT
-	if (TASK_IS_32BIT_ADDR)
-		rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
-	else
-#endif /* CONFIG_COMPAT */
-		rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
-
-	return rnd << PAGE_SHIFT;
-}
-
-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(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, rlim_stack);
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-	}
-}
-
 static inline unsigned long brk_rnd(void)
 {
 	unsigned long rnd = get_random_long();
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] riscv: Make mmap allocation top-down by default
  2019-03-22  7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
                   ` (2 preceding siblings ...)
  2019-03-22  7:42 ` [PATCH 3/4] mips: " Alexandre Ghiti
@ 2019-03-22  7:42 ` Alexandre Ghiti
  2019-03-22 13:22   ` Christoph Hellwig
  3 siblings, 1 reply; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22  7:42 UTC (permalink / raw)
  To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm
  Cc: Alexandre Ghiti

In order to avoid wasting user address space by using bottom-up mmap
allocation scheme, prefer top-down scheme when possible.

Before:
root@qemuriscv64:~# cat /proc/self/maps
00010000-00016000 r-xp 00000000 fe:00 6389       /bin/cat.coreutils
00016000-00017000 r--p 00005000 fe:00 6389       /bin/cat.coreutils
00017000-00018000 rw-p 00006000 fe:00 6389       /bin/cat.coreutils
00018000-00039000 rw-p 00000000 00:00 0          [heap]
1555556000-155556d000 r-xp 00000000 fe:00 7193   /lib/ld-2.28.so
155556d000-155556e000 r--p 00016000 fe:00 7193   /lib/ld-2.28.so
155556e000-155556f000 rw-p 00017000 fe:00 7193   /lib/ld-2.28.so
155556f000-1555570000 rw-p 00000000 00:00 0
1555570000-1555572000 r-xp 00000000 00:00 0      [vdso]
1555574000-1555576000 rw-p 00000000 00:00 0
1555576000-1555674000 r-xp 00000000 fe:00 7187   /lib/libc-2.28.so
1555674000-1555678000 r--p 000fd000 fe:00 7187   /lib/libc-2.28.so
1555678000-155567a000 rw-p 00101000 fe:00 7187   /lib/libc-2.28.so
155567a000-15556a0000 rw-p 00000000 00:00 0
3fffb90000-3fffbb1000 rw-p 00000000 00:00 0      [stack]

After:
root@qemuriscv64:~# cat /proc/self/maps
00010000-00016000 r-xp 00000000 fe:00 6389       /bin/cat.coreutils
00016000-00017000 r--p 00005000 fe:00 6389       /bin/cat.coreutils
00017000-00018000 rw-p 00006000 fe:00 6389       /bin/cat.coreutils
00018000-00039000 rw-p 00000000 00:00 0          [heap]
3ff7eb6000-3ff7ed8000 rw-p 00000000 00:00 0
3ff7ed8000-3ff7fd6000 r-xp 00000000 fe:00 7187   /lib/libc-2.28.so
3ff7fd6000-3ff7fda000 r--p 000fd000 fe:00 7187   /lib/libc-2.28.so
3ff7fda000-3ff7fdc000 rw-p 00101000 fe:00 7187   /lib/libc-2.28.so
3ff7fdc000-3ff7fe2000 rw-p 00000000 00:00 0
3ff7fe4000-3ff7fe6000 r-xp 00000000 00:00 0      [vdso]
3ff7fe6000-3ff7ffd000 r-xp 00000000 fe:00 7193   /lib/ld-2.28.so
3ff7ffd000-3ff7ffe000 r--p 00016000 fe:00 7193   /lib/ld-2.28.so
3ff7ffe000-3ff7fff000 rw-p 00017000 fe:00 7193   /lib/ld-2.28.so
3ff7fff000-3ff8000000 rw-p 00000000 00:00 0
3fff888000-3fff8a9000 rw-p 00000000 00:00 0      [stack]

Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
 arch/riscv/Kconfig                 | 12 ++++++++++++
 arch/riscv/include/asm/processor.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index eb56c82d8aa1..7661335d1667 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -50,6 +50,18 @@ config RISCV
 	select ARCH_HAS_PTE_SPECIAL
 	select HAVE_EBPF_JIT if 64BIT
 
+config HAVE_ARCH_MMAP_RND_BITS
+	def_bool y
+
+config ARCH_MMAP_RND_BITS_MIN
+	default 18
+
+# max bits determined by the following formula:
+#  VA_BITS - PAGE_SHIFT - 3
+config ARCH_MMAP_RND_BITS_MAX
+	default 33 if 64BIT # SV48 based
+	default 18
+
 config MMU
 	def_bool y
 
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index ce70bceb8872..e68a1b1e144a 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -23,6 +23,7 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE / 3)
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 
 #define STACK_TOP		TASK_SIZE
 #define STACK_TOP_MAX		STACK_TOP
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
  2019-03-22  7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
@ 2019-03-22 13:21   ` Christoph Hellwig
  2019-03-23  8:18     ` Alex Ghiti
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2019-03-22 13:21 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm

> It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
> that can be defined by other architectures to benefit from those functions.

Can you make this a Kconfig option defined in arch/Kconfig or mm/Kconfig
and selected by the architectures?

> -#ifndef STACK_RND_MASK
> -#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))	/* 8MB of VA */
> -#endif
> -
> -static unsigned long randomize_stack_top(unsigned long stack_top)
> -{
> -	unsigned long random_variable = 0;
> -
> -	if (current->flags & PF_RANDOMIZE) {
> -		random_variable = get_random_long();
> -		random_variable &= STACK_RND_MASK;
> -		random_variable <<= PAGE_SHIFT;
> -	}
> -#ifdef CONFIG_STACK_GROWSUP
> -	return PAGE_ALIGN(stack_top) + random_variable;
> -#else
> -	return PAGE_ALIGN(stack_top) - random_variable;
> -#endif
> -}
> -

Maybe the move of this function can be split into another prep patch,
as it is only very lightly related?

> +#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
> +	defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)

Not sure if it is wrіtten down somehwere or just convention, but I
general see cpp defined statements aligned with spaces to the
one on the previous line.

Except for these nitpicks this looks very nice to me, thanks for doing
this work!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] riscv: Make mmap allocation top-down by default
  2019-03-22  7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
@ 2019-03-22 13:22   ` Christoph Hellwig
  2019-03-23  8:05     ` Alex Ghiti
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2019-03-22 13:22 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
	Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
	Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
	linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
	linux-fsdevel, linux-mm

> +config HAVE_ARCH_MMAP_RND_BITS
> +	def_bool y

This already is defined in arch/Kconfig, no need to duplicate it
here, just add a select statement.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] riscv: Make mmap allocation top-down by default
  2019-03-22 13:22   ` Christoph Hellwig
@ 2019-03-23  8:05     ` Alex Ghiti
  0 siblings, 0 replies; 9+ messages in thread
From: Alex Ghiti @ 2019-03-23  8:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Russell King, Catalin Marinas, Will Deacon, Ralf Baechle,
	Paul Burton, James Hogan, Palmer Dabbelt, Albert Ou,
	Alexander Viro, Luis Chamberlain, Kees Cook, linux-arm-kernel,
	linux-kernel, linux-mips, linux-riscv, linux-fsdevel, linux-mm

On 3/22/19 9:22 AM, Christoph Hellwig wrote:
>> +config HAVE_ARCH_MMAP_RND_BITS
>> +	def_bool y
> This already is defined in arch/Kconfig, no need to duplicate it
> here, just add a select statement.
Right, I will fix that,

Thanks Christoph,

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
  2019-03-22 13:21   ` Christoph Hellwig
@ 2019-03-23  8:18     ` Alex Ghiti
  0 siblings, 0 replies; 9+ messages in thread
From: Alex Ghiti @ 2019-03-23  8:18 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Russell King, Catalin Marinas, Will Deacon, Ralf Baechle,
	Paul Burton, James Hogan, Palmer Dabbelt, Albert Ou,
	Alexander Viro, Luis Chamberlain, Kees Cook, linux-arm-kernel,
	linux-kernel, linux-mips, linux-riscv, linux-fsdevel, linux-mm

On 3/22/19 9:21 AM, Christoph Hellwig wrote:
>> It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
>> that can be defined by other architectures to benefit from those functions.
> Can you make this a Kconfig option defined in arch/Kconfig or mm/Kconfig
> and selected by the architectures?


Yes, I will do.


>> -#ifndef STACK_RND_MASK
>> -#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))	/* 8MB of VA */
>> -#endif
>> -
>> -static unsigned long randomize_stack_top(unsigned long stack_top)
>> -{
>> -	unsigned long random_variable = 0;
>> -
>> -	if (current->flags & PF_RANDOMIZE) {
>> -		random_variable = get_random_long();
>> -		random_variable &= STACK_RND_MASK;
>> -		random_variable <<= PAGE_SHIFT;
>> -	}
>> -#ifdef CONFIG_STACK_GROWSUP
>> -	return PAGE_ALIGN(stack_top) + random_variable;
>> -#else
>> -	return PAGE_ALIGN(stack_top) - random_variable;
>> -#endif
>> -}
>> -
> Maybe the move of this function can be split into another prep patch,
> as it is only very lightly related?
>
>

Ok, that makes sense.

>> +#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
>> +	defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
> Not sure if it is wrіtten down somehwere or just convention, but I
> general see cpp defined statements aligned with spaces to the
> one on the previous line.


Ok, I will fix that.


> Except for these nitpicks this looks very nice to me, thanks for doing
> this work!


Thanks :)


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-03-23  8:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-22  7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
2019-03-22  7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
2019-03-22 13:21   ` Christoph Hellwig
2019-03-23  8:18     ` Alex Ghiti
2019-03-22  7:42 ` [PATCH 2/4] arm: Use generic mmap top-down layout Alexandre Ghiti
2019-03-22  7:42 ` [PATCH 3/4] mips: " Alexandre Ghiti
2019-03-22  7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
2019-03-22 13:22   ` Christoph Hellwig
2019-03-23  8:05     ` Alex Ghiti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).