* [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm
2019-04-04 5:51 [PATCH v2 0/5] Provide generic top-down mmap layout functions Alexandre Ghiti
@ 2019-04-04 5:51 ` Alexandre Ghiti
2019-04-10 6:54 ` Christoph Hellwig
2019-04-04 5:51 ` [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions " Alexandre Ghiti
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-04 5:51 UTC (permalink / raw)
To: Andrew Morton
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, Alexandre Ghiti
This preparatory commit moves this function so that further introduction
of generic topdown mmap layout is contained only in mm/util.c.
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
fs/binfmt_elf.c | 20 --------------------
include/linux/mm.h | 2 ++
mm/util.c | 22 ++++++++++++++++++++++
3 files changed, 24 insertions(+), 20 deletions(-)
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/mm/util.c b/mm/util.c
index d559bde497a9..a54afb9b4faa 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -14,6 +14,8 @@
#include <linux/hugetlb.h>
#include <linux/vmalloc.h>
#include <linux/userfaultfd_k.h>
+#include <linux/elf.h>
+#include <linux/random.h>
#include <linux/uaccess.h>
@@ -291,6 +293,26 @@ int vma_is_stack_for_current(struct vm_area_struct *vma)
return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
}
+#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
+}
+
#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
{
--
2.20.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm
2019-04-04 5:51 ` [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm Alexandre Ghiti
@ 2019-04-10 6:54 ` Christoph Hellwig
2019-04-10 7:18 ` Alexandre Ghiti
0 siblings, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2019-04-10 6:54 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Andrew Morton, Albert Ou, Kees Cook, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, Christoph Hellwig, linux-mm, Paul Burton,
Alexander Viro, James Hogan, linux-fsdevel, linux-riscv,
linux-mips, linux-arm-kernel, Luis Chamberlain
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm
2019-04-10 6:54 ` Christoph Hellwig
@ 2019-04-10 7:18 ` Alexandre Ghiti
0 siblings, 0 replies; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-10 7:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Albert Ou, Kees Cook, Catalin Marinas, Palmer Dabbelt,
Will Deacon, Russell King, Ralf Baechle, linux-kernel, linux-mm,
Paul Burton, Alexander Viro, James Hogan, linux-fsdevel,
Andrew Morton, linux-mips, linux-riscv, linux-arm-kernel,
Luis Chamberlain
On 04/10/2019 08:54 AM, Christoph Hellwig wrote:
> Looks good,
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
Thanks Christoph,
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions to mm
2019-04-04 5:51 [PATCH v2 0/5] Provide generic top-down mmap layout functions Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm Alexandre Ghiti
@ 2019-04-04 5:51 ` Alexandre Ghiti
2019-04-10 6:59 ` Christoph Hellwig
2019-04-04 5:51 ` [PATCH v2 3/5] arm: Use generic mmap top-down layout Alexandre Ghiti
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-04 5:51 UTC (permalink / raw)
To: Andrew Morton
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, 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 config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
that can be set by other architectures to benefit from those functions.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
arch/Kconfig | 8 ++++
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/processor.h | 2 -
arch/arm64/mm/mmap.c | 72 ----------------------------
kernel/sysctl.c | 6 ++-
mm/util.c | 77 +++++++++++++++++++++++++++++-
6 files changed, 89 insertions(+), 77 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 33687dddd86a..ef8d0b50cc41 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -684,6 +684,14 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
and vice-versa 32-bit applications to call 64-bit mmap().
Required for applications doing different bitness syscalls.
+config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
+ bool
+ help
+ This allows to use a set of generic functions to determine mmap base
+ address by giving priority to top-down scheme only if the process
+ is not in legacy mode (compat task, unlimited stack size or
+ sysctl_legacy_va_layout).
+
config HAVE_COPY_THREAD_TLS
bool
help
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7e34b9eba5de..670719a26b45 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -66,6 +66,7 @@ config ARM64
select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG
select ARCH_SUPPORTS_NUMA_BALANCING
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
+ select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
select ARCH_WANT_FRAME_POINTERS
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARM_AMBA
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5d9ce62bdebd..4de2a2fd605a 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -274,8 +274,6 @@ static inline void spin_lock_prefetch(const void *ptr)
"nop") : : "p" (ptr));
}
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
#endif
extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */
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/kernel/sysctl.c b/kernel/sysctl.c
index e5da394d1ca3..eb3414e78986 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(CONFIG_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(CONFIG_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 a54afb9b4faa..2027457ec30d 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -15,7 +15,12 @@
#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>
@@ -313,13 +318,83 @@ unsigned long randomize_stack_top(unsigned long stack_top)
#endif
}
-#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
+#ifdef CONFIG_MMU
+#ifdef CONFIG_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] 14+ messages in thread
* Re: [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions to mm
2019-04-04 5:51 ` [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions " Alexandre Ghiti
@ 2019-04-10 6:59 ` Christoph Hellwig
2019-04-10 7:32 ` Alexandre Ghiti
0 siblings, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2019-04-10 6:59 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Andrew Morton, Albert Ou, Kees Cook, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, Christoph Hellwig, linux-mm, Paul Burton,
Alexander Viro, James Hogan, linux-fsdevel, linux-riscv,
linux-mips, linux-arm-kernel, Luis Chamberlain
On Thu, Apr 04, 2019 at 01:51:25AM -0400, Alexandre Ghiti wrote:
> - fix the case where stack randomization should not be taken into
> account.
Hmm. This sounds a bit vague. It might be better if something
considered a fix is split out to a separate patch with a good
description.
> +config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
> + bool
> + help
> + This allows to use a set of generic functions to determine mmap base
> + address by giving priority to top-down scheme only if the process
> + is not in legacy mode (compat task, unlimited stack size or
> + sysctl_legacy_va_layout).
Given that this is an option that is just selected by other Kconfig
options the help text won't ever be shown. I'd just move it into a
comment bove the definition.
> +#ifdef CONFIG_MMU
> +#ifdef CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
I don't think we need the #ifdef CONFIG_MMU here,
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT should only be selected
if the MMU is enabled to start with.
> +#ifdef CONFIG_ARCH_HAS_ELF_RANDOMIZE
> +unsigned long arch_mmap_rnd(void)
Now that a bunch of architectures use a version in common code
the arch_ prefix is a bit mislead. Probably not worth changing
here, but some time in the future it could use a new name.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions to mm
2019-04-10 6:59 ` Christoph Hellwig
@ 2019-04-10 7:32 ` Alexandre Ghiti
2019-04-10 18:27 ` Kees Cook
0 siblings, 1 reply; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-10 7:32 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Albert Ou, Kees Cook, Catalin Marinas, Palmer Dabbelt,
Will Deacon, Russell King, Ralf Baechle, linux-kernel, linux-mm,
Paul Burton, Alexander Viro, James Hogan, linux-fsdevel,
Andrew Morton, linux-mips, linux-riscv, linux-arm-kernel,
Luis Chamberlain
On 04/10/2019 08:59 AM, Christoph Hellwig wrote:
> On Thu, Apr 04, 2019 at 01:51:25AM -0400, Alexandre Ghiti wrote:
>> - fix the case where stack randomization should not be taken into
>> account.
> Hmm. This sounds a bit vague. It might be better if something
> considered a fix is split out to a separate patch with a good
> description.
Ok, I will move this fix in another patch.
>
>> +config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
>> + bool
>> + help
>> + This allows to use a set of generic functions to determine mmap base
>> + address by giving priority to top-down scheme only if the process
>> + is not in legacy mode (compat task, unlimited stack size or
>> + sysctl_legacy_va_layout).
> Given that this is an option that is just selected by other Kconfig
> options the help text won't ever be shown. I'd just move it into a
> comment bove the definition.
Oh yes, it does not appear, thanks, I'll move it above the definition.
>
>> +#ifdef CONFIG_MMU
>> +#ifdef CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
> I don't think we need the #ifdef CONFIG_MMU here,
> CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT should only be selected
> if the MMU is enabled to start with.
Ok, thanks.
>> +#ifdef CONFIG_ARCH_HAS_ELF_RANDOMIZE
>> +unsigned long arch_mmap_rnd(void)
> Now that a bunch of architectures use a version in common code
> the arch_ prefix is a bit mislead. Probably not worth changing
> here, but some time in the future it could use a new name.
Ok I'll keep it in mind for later,
Thanks for your time,
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions to mm
2019-04-10 7:32 ` Alexandre Ghiti
@ 2019-04-10 18:27 ` Kees Cook
2019-04-11 7:16 ` Alexandre Ghiti
0 siblings, 1 reply; 14+ messages in thread
From: Kees Cook @ 2019-04-10 18:27 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Christoph Hellwig, Albert Ou, Kees Cook, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle, LKML,
Linux-MM, Paul Burton, Alexander Viro, James Hogan,
linux-fsdevel, Andrew Morton, linux-mips, linux-riscv,
linux-arm-kernel, Luis Chamberlain
On Wed, Apr 10, 2019 at 12:33 AM Alexandre Ghiti <alex@ghiti.fr> wrote:
>
> On 04/10/2019 08:59 AM, Christoph Hellwig wrote:
> > On Thu, Apr 04, 2019 at 01:51:25AM -0400, Alexandre Ghiti wrote:
> >> - fix the case where stack randomization should not be taken into
> >> account.
> > Hmm. This sounds a bit vague. It might be better if something
> > considered a fix is split out to a separate patch with a good
> > description.
>
> Ok, I will move this fix in another patch.
Yeah, I think it'd be best to break this into a few (likely small) patches:
- update the compat case in the arm64 code
- fix the "not randomized" case
- move the code to mm/ (line-for-line identical for easy review)
That'll make it much easier to review (at least for me).
Thanks!
--
Kees Cook
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions to mm
2019-04-10 18:27 ` Kees Cook
@ 2019-04-11 7:16 ` Alexandre Ghiti
0 siblings, 0 replies; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-11 7:16 UTC (permalink / raw)
To: Kees Cook
Cc: Albert Ou, Catalin Marinas, Palmer Dabbelt, Will Deacon,
Russell King, Ralf Baechle, LKML, Christoph Hellwig, Linux-MM,
Paul Burton, Alexander Viro, James Hogan, linux-fsdevel,
Andrew Morton, linux-mips, linux-riscv, linux-arm-kernel,
Luis Chamberlain
On 04/10/2019 08:27 PM, Kees Cook wrote:
> On Wed, Apr 10, 2019 at 12:33 AM Alexandre Ghiti <alex@ghiti.fr> wrote:
>> On 04/10/2019 08:59 AM, Christoph Hellwig wrote:
>>> On Thu, Apr 04, 2019 at 01:51:25AM -0400, Alexandre Ghiti wrote:
>>>> - fix the case where stack randomization should not be taken into
>>>> account.
>>> Hmm. This sounds a bit vague. It might be better if something
>>> considered a fix is split out to a separate patch with a good
>>> description.
>> Ok, I will move this fix in another patch.
> Yeah, I think it'd be best to break this into a few (likely small) patches:
> - update the compat case in the arm64 code
> - fix the "not randomized" case
> - move the code to mm/ (line-for-line identical for easy review)
>
> That'll make it much easier to review (at least for me).
>
> Thanks!
>
Sorry about that, I'm working on it.
Thanks,
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 3/5] arm: Use generic mmap top-down layout
2019-04-04 5:51 [PATCH v2 0/5] Provide generic top-down mmap layout functions Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 1/5] mm, fs: Move randomize_stack_top from fs to mm Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 2/5] arm64, mm: Move generic mmap layout functions " Alexandre Ghiti
@ 2019-04-04 5:51 ` Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 4/5] mips: " Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 5/5] riscv: Make mmap allocation top-down by default Alexandre Ghiti
4 siblings, 0 replies; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-04 5:51 UTC (permalink / raw)
To: Andrew Morton
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, 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/Kconfig | 1 +
arch/arm/include/asm/processor.h | 2 --
arch/arm/mm/mmap.c | 52 --------------------------------
3 files changed, 1 insertion(+), 54 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 850b4805e2d1..747101a8e989 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -28,6 +28,7 @@ config ARM
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
select ARCH_WANT_IPC_PARSE_VERSION
select BUILDTIME_EXTABLE_SORT if MMU
select CLONE_BACKWARDS
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 57fe73ea0f72..944ef1fb1237 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -143,8 +143,6 @@ static inline void prefetchw(const void *ptr)
#endif
#endif
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
#endif
#endif /* __ASM_ARM_PROCESSOR_H */
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] 14+ messages in thread
* [PATCH v2 4/5] mips: Use generic mmap top-down layout
2019-04-04 5:51 [PATCH v2 0/5] Provide generic top-down mmap layout functions Alexandre Ghiti
` (2 preceding siblings ...)
2019-04-04 5:51 ` [PATCH v2 3/5] arm: Use generic mmap top-down layout Alexandre Ghiti
@ 2019-04-04 5:51 ` Alexandre Ghiti
2019-04-04 5:51 ` [PATCH v2 5/5] riscv: Make mmap allocation top-down by default Alexandre Ghiti
4 siblings, 0 replies; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-04 5:51 UTC (permalink / raw)
To: Andrew Morton
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, 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/Kconfig | 1 +
arch/mips/include/asm/processor.h | 5 ---
arch/mips/mm/mmap.c | 57 -------------------------------
3 files changed, 1 insertion(+), 62 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4a5f5b0ee9a9..c21aa6371eab 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -14,6 +14,7 @@ config MIPS
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
select ARCH_WANT_IPC_PARSE_VERSION
select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index aca909bd7841..fba18d4a9190 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -29,11 +29,6 @@
extern unsigned int vced_count, vcei_count;
-/*
- * MIPS does have an arch_pick_mmap_layout()
- */
-#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
-
#ifdef CONFIG_32BIT
#ifdef CONFIG_KVM_GUEST
/* User space process size is limited to 1GB in KVM Guest Mode */
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] 14+ messages in thread
* [PATCH v2 5/5] riscv: Make mmap allocation top-down by default
2019-04-04 5:51 [PATCH v2 0/5] Provide generic top-down mmap layout functions Alexandre Ghiti
` (3 preceding siblings ...)
2019-04-04 5:51 ` [PATCH v2 4/5] mips: " Alexandre Ghiti
@ 2019-04-04 5:51 ` Alexandre Ghiti
2019-04-10 6:59 ` Christoph Hellwig
4 siblings, 1 reply; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-04 5:51 UTC (permalink / raw)
To: Andrew Morton
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, 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 | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index eb56c82d8aa1..fe09f38ef9a9 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -49,6 +49,17 @@ config RISCV
select GENERIC_IRQ_MULTI_HANDLER
select ARCH_HAS_PTE_SPECIAL
select HAVE_EBPF_JIT if 64BIT
+ select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
+ select HAVE_ARCH_MMAP_RND_BITS
+
+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
--
2.20.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 5/5] riscv: Make mmap allocation top-down by default
2019-04-04 5:51 ` [PATCH v2 5/5] riscv: Make mmap allocation top-down by default Alexandre Ghiti
@ 2019-04-10 6:59 ` Christoph Hellwig
2019-04-10 7:18 ` Alexandre Ghiti
0 siblings, 1 reply; 14+ messages in thread
From: Christoph Hellwig @ 2019-04-10 6:59 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Andrew Morton, Albert Ou, Kees Cook, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, Christoph Hellwig, linux-mm, Paul Burton,
Alexander Viro, James Hogan, linux-fsdevel, linux-riscv,
linux-mips, linux-arm-kernel, Luis Chamberlain
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 5/5] riscv: Make mmap allocation top-down by default
2019-04-10 6:59 ` Christoph Hellwig
@ 2019-04-10 7:18 ` Alexandre Ghiti
0 siblings, 0 replies; 14+ messages in thread
From: Alexandre Ghiti @ 2019-04-10 7:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Andrew Morton, Albert Ou, Kees Cook, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, linux-mm, Paul Burton, Alexander Viro, James Hogan,
linux-fsdevel, linux-riscv, linux-mips, linux-arm-kernel,
Luis Chamberlain
On 04/10/2019 08:59 AM, Christoph Hellwig wrote:
> Looks good,
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
Thanks Christoph,
Alex
^ permalink raw reply [flat|nested] 14+ messages in thread