mmap.c (e8d54b62c55ab6201de6d195fc2c276294c1f6ae) mmap.c (67f3977f805b34cf0e41090679800d2091d41d49)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Based on arch/arm/mm/mmap.c
4 *
5 * Copyright (C) 2012 ARM Ltd.
6 */
7
8#include <linux/elf.h>

--- 7 unchanged lines hidden (view full) ---

16#include <linux/sched/mm.h>
17#include <linux/io.h>
18#include <linux/personality.h>
19#include <linux/random.h>
20
21#include <asm/cputype.h>
22
23/*
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Based on arch/arm/mm/mmap.c
4 *
5 * Copyright (C) 2012 ARM Ltd.
6 */
7
8#include <linux/elf.h>

--- 7 unchanged lines hidden (view full) ---

16#include <linux/sched/mm.h>
17#include <linux/io.h>
18#include <linux/personality.h>
19#include <linux/random.h>
20
21#include <asm/cputype.h>
22
23/*
24 * Leave enough space between the mmap area and the stack to honour ulimit in
25 * the face of randomisation.
26 */
27#define MIN_GAP (SZ_128M)
28#define MAX_GAP (STACK_TOP/6*5)
29
30static int mmap_is_legacy(struct rlimit *rlim_stack)
31{
32 if (current->personality & ADDR_COMPAT_LAYOUT)
33 return 1;
34
35 if (rlim_stack->rlim_cur == RLIM_INFINITY)
36 return 1;
37
38 return sysctl_legacy_va_layout;
39}
40
41unsigned long arch_mmap_rnd(void)
42{
43 unsigned long rnd;
44
45#ifdef CONFIG_COMPAT
46 if (is_compat_task())
47 rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
48 else
49#endif
50 rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
51 return rnd << PAGE_SHIFT;
52}
53
54static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
55{
56 unsigned long gap = rlim_stack->rlim_cur;
57 unsigned long pad = stack_guard_gap;
58
59 /* Account for stack randomization if necessary */
60 if (current->flags & PF_RANDOMIZE)
61 pad += (STACK_RND_MASK << PAGE_SHIFT);
62
63 /* Values close to RLIM_INFINITY can overflow. */
64 if (gap + pad > gap)
65 gap += pad;
66
67 if (gap < MIN_GAP)
68 gap = MIN_GAP;
69 else if (gap > MAX_GAP)
70 gap = MAX_GAP;
71
72 return PAGE_ALIGN(STACK_TOP - gap - rnd);
73}
74
75/*
76 * This function, called very early during the creation of a new process VM
77 * image, sets up which VM layout function to use:
78 */
79void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
80{
81 unsigned long random_factor = 0UL;
82
83 if (current->flags & PF_RANDOMIZE)
84 random_factor = arch_mmap_rnd();
85
86 /*
87 * Fall back to the standard layout if the personality bit is set, or
88 * if the expected stack growth is unlimited:
89 */
90 if (mmap_is_legacy(rlim_stack)) {
91 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
92 mm->get_unmapped_area = arch_get_unmapped_area;
93 } else {
94 mm->mmap_base = mmap_base(random_factor, rlim_stack);
95 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
96 }
97}
98
99/*
100 * You really shouldn't be using read() or write() on /dev/mem. This might go
101 * away in the future.
102 */
103int valid_phys_addr_range(phys_addr_t addr, size_t size)
104{
105 /*
106 * Check whether addr is covered by a memory region without the
107 * MEMBLOCK_NOMAP attribute, and whether that region covers the

--- 39 unchanged lines hidden ---
24 * You really shouldn't be using read() or write() on /dev/mem. This might go
25 * away in the future.
26 */
27int valid_phys_addr_range(phys_addr_t addr, size_t size)
28{
29 /*
30 * Check whether addr is covered by a memory region without the
31 * MEMBLOCK_NOMAP attribute, and whether that region covers the

--- 39 unchanged lines hidden ---