1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * Taken from the i386 architecture and simplified. 15 */ 16 17#include <linux/mm.h> 18#include <linux/random.h> 19#include <linux/limits.h> 20#include <linux/sched/signal.h> 21#include <linux/sched/mm.h> 22#include <linux/mman.h> 23#include <linux/compat.h> 24 25/* 26 * Top of mmap area (just below the process stack). 27 * 28 * Leave an at least ~128 MB hole. 29 */ 30#define MIN_GAP (128*1024*1024) 31#define MAX_GAP (TASK_SIZE/6*5) 32 33static inline unsigned long mmap_base(struct mm_struct *mm) 34{ 35 unsigned long gap = rlimit(RLIMIT_STACK); 36 unsigned long random_factor = 0; 37 38 if (current->flags & PF_RANDOMIZE) 39 random_factor = get_random_int() % (1024*1024); 40 41 if (gap < MIN_GAP) 42 gap = MIN_GAP; 43 else if (gap > MAX_GAP) 44 gap = MAX_GAP; 45 46 return PAGE_ALIGN(TASK_SIZE - gap - random_factor); 47} 48 49/* 50 * This function, called very early during the creation of a new 51 * process VM image, sets up which VM layout function to use: 52 */ 53void arch_pick_mmap_layout(struct mm_struct *mm) 54{ 55#if !defined(__tilegx__) 56 int is_32bit = 1; 57#elif defined(CONFIG_COMPAT) 58 int is_32bit = is_compat_task(); 59#else 60 int is_32bit = 0; 61#endif 62 unsigned long random_factor = 0UL; 63 64 /* 65 * 8 bits of randomness in 32bit mmaps, 24 address space bits 66 * 12 bits of randomness in 64bit mmaps, 28 address space bits 67 */ 68 if (current->flags & PF_RANDOMIZE) { 69 if (is_32bit) 70 random_factor = get_random_int() % (1<<8); 71 else 72 random_factor = get_random_int() % (1<<12); 73 74 random_factor <<= PAGE_SHIFT; 75 } 76 77 /* 78 * Use standard layout if the expected stack growth is unlimited 79 * or we are running native 64 bits. 80 */ 81 if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) { 82 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; 83 mm->get_unmapped_area = arch_get_unmapped_area; 84 } else { 85 mm->mmap_base = mmap_base(mm); 86 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 87 } 88} 89 90unsigned long arch_randomize_brk(struct mm_struct *mm) 91{ 92 return randomize_page(mm->brk, 0x02000000); 93} 94