summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Ghiti <alex@ghiti.fr>2019-09-23 18:38:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-24 18:54:11 -0400
commit649775be63c8b2e0b56ecc5bbc96d38205ec5259 (patch)
tree3f27e84d177715016de872a77f881a5a50807376
parentf385cb85a42fc4ba92464c2bfd2e2049d65353d3 (diff)
mm, fs: move randomize_stack_top from fs to mm
Patch series "Provide generic top-down mmap layout functions", v6. 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 This patch (of 14): This preparatory commit moves this function so that further introduction of generic topdown mmap layout is contained only in mm/util.c. Link: http://lkml.kernel.org/r/20190730055113.23635-2-alex@ghiti.fr Signed-off-by: Alexandre Ghiti <alex@ghiti.fr> Acked-by: Kees Cook <keescook@chromium.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Cc: Russell King <linux@armlinux.org.uk> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Burton <paul.burton@mips.com> Cc: James Hogan <jhogan@kernel.org> Cc: Palmer Dabbelt <palmer@sifive.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/binfmt_elf.c20
-rw-r--r--include/linux/mm.h2
-rw-r--r--mm/util.c22
3 files changed, 24 insertions, 20 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d4e11b2e04f6..cec3b4146440 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -670,26 +670,6 @@ out:
670 * libraries. There is no binary dependent code anywhere else. 670 * libraries. There is no binary dependent code anywhere else.
671 */ 671 */
672 672
673#ifndef STACK_RND_MASK
674#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
675#endif
676
677static unsigned long randomize_stack_top(unsigned long stack_top)
678{
679 unsigned long random_variable = 0;
680
681 if (current->flags & PF_RANDOMIZE) {
682 random_variable = get_random_long();
683 random_variable &= STACK_RND_MASK;
684 random_variable <<= PAGE_SHIFT;
685 }
686#ifdef CONFIG_STACK_GROWSUP
687 return PAGE_ALIGN(stack_top) + random_variable;
688#else
689 return PAGE_ALIGN(stack_top) - random_variable;
690#endif
691}
692
693static int load_elf_binary(struct linux_binprm *bprm) 673static int load_elf_binary(struct linux_binprm *bprm)
694{ 674{
695 struct file *interpreter = NULL; /* to shut gcc up */ 675 struct file *interpreter = NULL; /* to shut gcc up */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 233ad11938db..294a67b94147 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2328,6 +2328,8 @@ extern int install_special_mapping(struct mm_struct *mm,
2328 unsigned long addr, unsigned long len, 2328 unsigned long addr, unsigned long len,
2329 unsigned long flags, struct page **pages); 2329 unsigned long flags, struct page **pages);
2330 2330
2331unsigned long randomize_stack_top(unsigned long stack_top);
2332
2331extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 2333extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
2332 2334
2333extern unsigned long mmap_region(struct file *file, unsigned long addr, 2335extern unsigned long mmap_region(struct file *file, unsigned long addr,
diff --git a/mm/util.c b/mm/util.c
index 37f7b6711514..bf8af5e07c4a 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -16,6 +16,8 @@
16#include <linux/hugetlb.h> 16#include <linux/hugetlb.h>
17#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
18#include <linux/userfaultfd_k.h> 18#include <linux/userfaultfd_k.h>
19#include <linux/elf.h>
20#include <linux/random.h>
19 21
20#include <linux/uaccess.h> 22#include <linux/uaccess.h>
21 23
@@ -293,6 +295,26 @@ int vma_is_stack_for_current(struct vm_area_struct *vma)
293 return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); 295 return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
294} 296}
295 297
298#ifndef STACK_RND_MASK
299#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
300#endif
301
302unsigned long randomize_stack_top(unsigned long stack_top)
303{
304 unsigned long random_variable = 0;
305
306 if (current->flags & PF_RANDOMIZE) {
307 random_variable = get_random_long();
308 random_variable &= STACK_RND_MASK;
309 random_variable <<= PAGE_SHIFT;
310 }
311#ifdef CONFIG_STACK_GROWSUP
312 return PAGE_ALIGN(stack_top) + random_variable;
313#else
314 return PAGE_ALIGN(stack_top) - random_variable;
315#endif
316}
317
296#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT) 318#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
297void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) 319void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
298{ 320{