1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * flexible mmap layout support 4 * 5 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 6 * All Rights Reserved. 7 * 8 * Started by Ingo Molnar <mingo@elte.hu> 9 */ 10 11#include <linux/personality.h> 12#include <linux/mm.h> 13#include <linux/random.h> 14#include <linux/sched/signal.h> 15#include <linux/sched/mm.h> 16#include <linux/elf-randomize.h> 17#include <linux/security.h> 18#include <linux/mman.h> 19 20/* 21 * Top of mmap area (just below the process stack). 22 * 23 * Leave at least a ~128 MB hole. 24 */ 25#define MIN_GAP (128*1024*1024) 26#define MAX_GAP (TASK_SIZE/6*5) 27 28static inline int mmap_is_legacy(struct rlimit *rlim_stack) 29{ 30 if (current->personality & ADDR_COMPAT_LAYOUT) 31 return 1; 32 33 if (rlim_stack->rlim_cur == RLIM_INFINITY) 34 return 1; 35 36 return sysctl_legacy_va_layout; 37} 38 39unsigned long arch_mmap_rnd(void) 40{ 41 unsigned long shift, rnd; 42 43 shift = mmap_rnd_bits; 44#ifdef CONFIG_COMPAT 45 if (is_32bit_task()) 46 shift = mmap_rnd_compat_bits; 47#endif 48 rnd = get_random_long() % (1ul << shift); 49 50 return rnd << PAGE_SHIFT; 51} 52 53static inline unsigned long stack_maxrandom_size(void) 54{ 55 if (!(current->flags & PF_RANDOMIZE)) 56 return 0; 57 58 /* 8MB for 32bit, 1GB for 64bit */ 59 if (is_32bit_task()) 60 return (1<<23); 61 else 62 return (1<<30); 63} 64 65static inline unsigned long mmap_base(unsigned long rnd, 66 struct rlimit *rlim_stack) 67{ 68 unsigned long gap = rlim_stack->rlim_cur; 69 unsigned long pad = stack_maxrandom_size() + stack_guard_gap; 70 71 /* Values close to RLIM_INFINITY can overflow. */ 72 if (gap + pad > gap) 73 gap += pad; 74 75 if (gap < MIN_GAP) 76 gap = MIN_GAP; 77 else if (gap > MAX_GAP) 78 gap = MAX_GAP; 79 80 return PAGE_ALIGN(DEFAULT_MAP_WINDOW - gap - rnd); 81} 82 83#ifdef CONFIG_PPC_RADIX_MMU 84/* 85 * Same function as generic code used only for radix, because we don't need to overload 86 * the generic one. But we will have to duplicate, because hash select 87 * HAVE_ARCH_UNMAPPED_AREA 88 */ 89static unsigned long 90radix__arch_get_unmapped_area(struct file *filp, unsigned long addr, 91 unsigned long len, unsigned long pgoff, 92 unsigned long flags) 93{ 94 struct mm_struct *mm = current->mm; 95 struct vm_area_struct *vma; 96 int fixed = (flags & MAP_FIXED); 97 unsigned long high_limit; 98 struct vm_unmapped_area_info info; 99 100 high_limit = DEFAULT_MAP_WINDOW; 101 if (addr >= high_limit || (fixed && (addr + len > high_limit))) 102 high_limit = TASK_SIZE; 103 104 if (len > high_limit) 105 return -ENOMEM; 106 107 if (fixed) { 108 if (addr > high_limit - len) 109 return -ENOMEM; 110 return addr; 111 } 112 113 if (addr) { 114 addr = PAGE_ALIGN(addr); 115 vma = find_vma(mm, addr); 116 if (high_limit - len >= addr && addr >= mmap_min_addr && 117 (!vma || addr + len <= vm_start_gap(vma))) 118 return addr; 119 } 120 121 info.flags = 0; 122 info.length = len; 123 info.low_limit = mm->mmap_base; 124 info.high_limit = high_limit; 125 info.align_mask = 0; 126 127 return vm_unmapped_area(&info); 128} 129 130static unsigned long 131radix__arch_get_unmapped_area_topdown(struct file *filp, 132 const unsigned long addr0, 133 const unsigned long len, 134 const unsigned long pgoff, 135 const unsigned long flags) 136{ 137 struct vm_area_struct *vma; 138 struct mm_struct *mm = current->mm; 139 unsigned long addr = addr0; 140 int fixed = (flags & MAP_FIXED); 141 unsigned long high_limit; 142 struct vm_unmapped_area_info info; 143 144 high_limit = DEFAULT_MAP_WINDOW; 145 if (addr >= high_limit || (fixed && (addr + len > high_limit))) 146 high_limit = TASK_SIZE; 147 148 if (len > high_limit) 149 return -ENOMEM; 150 151 if (fixed) { 152 if (addr > high_limit - len) 153 return -ENOMEM; 154 return addr; 155 } 156 157 if (addr) { 158 addr = PAGE_ALIGN(addr); 159 vma = find_vma(mm, addr); 160 if (high_limit - len >= addr && addr >= mmap_min_addr && 161 (!vma || addr + len <= vm_start_gap(vma))) 162 return addr; 163 } 164 165 info.flags = VM_UNMAPPED_AREA_TOPDOWN; 166 info.length = len; 167 info.low_limit = max(PAGE_SIZE, mmap_min_addr); 168 info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW); 169 info.align_mask = 0; 170 171 addr = vm_unmapped_area(&info); 172 if (!(addr & ~PAGE_MASK)) 173 return addr; 174 VM_BUG_ON(addr != -ENOMEM); 175 176 /* 177 * A failed mmap() very likely causes application failure, 178 * so fall back to the bottom-up function here. This scenario 179 * can happen with large stack limits and large mmap() 180 * allocations. 181 */ 182 return radix__arch_get_unmapped_area(filp, addr0, len, pgoff, flags); 183} 184 185static void radix__arch_pick_mmap_layout(struct mm_struct *mm, 186 unsigned long random_factor, 187 struct rlimit *rlim_stack) 188{ 189 if (mmap_is_legacy(rlim_stack)) { 190 mm->mmap_base = TASK_UNMAPPED_BASE; 191 mm->get_unmapped_area = radix__arch_get_unmapped_area; 192 } else { 193 mm->mmap_base = mmap_base(random_factor, rlim_stack); 194 mm->get_unmapped_area = radix__arch_get_unmapped_area_topdown; 195 } 196} 197#else 198/* dummy */ 199extern void radix__arch_pick_mmap_layout(struct mm_struct *mm, 200 unsigned long random_factor, 201 struct rlimit *rlim_stack); 202#endif 203/* 204 * This function, called very early during the creation of a new 205 * process VM image, sets up which VM layout function to use: 206 */ 207void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) 208{ 209 unsigned long random_factor = 0UL; 210 211 if (current->flags & PF_RANDOMIZE) 212 random_factor = arch_mmap_rnd(); 213 214 if (radix_enabled()) 215 return radix__arch_pick_mmap_layout(mm, random_factor, 216 rlim_stack); 217 /* 218 * Fall back to the standard layout if the personality 219 * bit is set, or if the expected stack growth is unlimited: 220 */ 221 if (mmap_is_legacy(rlim_stack)) { 222 mm->mmap_base = TASK_UNMAPPED_BASE; 223 mm->get_unmapped_area = arch_get_unmapped_area; 224 } else { 225 mm->mmap_base = mmap_base(random_factor, rlim_stack); 226 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 227 } 228} 229