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.h> 21#include <linux/mman.h> 22#include <linux/compat.h> 23 24/* 25 * Top of mmap area (just below the process stack). 26 * 27 * Leave an at least ~128 MB hole. 28 */ 29#define MIN_GAP (128*1024*1024) 30#define MAX_GAP (TASK_SIZE/6*5) 31 32static inline unsigned long mmap_base(struct mm_struct *mm) 33{ 34 unsigned long gap = rlimit(RLIMIT_STACK); 35 unsigned long random_factor = 0; 36 37 if (current->flags & PF_RANDOMIZE) 38 random_factor = get_random_int() % (1024*1024); 39 40 if (gap < MIN_GAP) 41 gap = MIN_GAP; 42 else if (gap > MAX_GAP) 43 gap = MAX_GAP; 44 45 return PAGE_ALIGN(TASK_SIZE - gap - random_factor); 46} 47 48/* 49 * This function, called very early during the creation of a new 50 * process VM image, sets up which VM layout function to use: 51 */ 52void arch_pick_mmap_layout(struct mm_struct *mm) 53{ 54#if !defined(__tilegx__) 55 int is_32bit = 1; 56#elif defined(CONFIG_COMPAT) 57 int is_32bit = is_compat_task(); 58#else 59 int is_32bit = 0; 60#endif 61 unsigned long random_factor = 0UL; 62 63 /* 64 * 8 bits of randomness in 32bit mmaps, 24 address space bits 65 * 12 bits of randomness in 64bit mmaps, 28 address space bits 66 */ 67 if (current->flags & PF_RANDOMIZE) { 68 if (is_32bit) 69 random_factor = get_random_int() % (1<<8); 70 else 71 random_factor = get_random_int() % (1<<12); 72 73 random_factor <<= PAGE_SHIFT; 74 } 75 76 /* 77 * Use standard layout if the expected stack growth is unlimited 78 * or we are running native 64 bits. 79 */ 80 if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) { 81 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; 82 mm->get_unmapped_area = arch_get_unmapped_area; 83 } else { 84 mm->mmap_base = mmap_base(mm); 85 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 86 } 87} 88 89unsigned long arch_randomize_brk(struct mm_struct *mm) 90{ 91 unsigned long range_end = mm->brk + 0x02000000; 92 return randomize_range(mm->brk, range_end, 0) ? : mm->brk; 93} 94