diff options
author | Kees Cook <keescook@chromium.org> | 2015-04-14 18:47:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-14 19:49:05 -0400 |
commit | 82168140bc4cec7ec9bad39705518541149ff8b7 (patch) | |
tree | 204435faeddb6c911c8dba3313da288ccef29f55 /arch/x86 | |
parent | fbbc400f3924ce095b466c776dc294727ec0a202 (diff) |
x86: standardize mmap_rnd() usage
In preparation for splitting out ET_DYN ASLR, this refactors the use of
mmap_rnd() to be used similarly to arm, and extracts the checking of
PF_RANDOMIZE.
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/mm/mmap.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index df4552bd239e..ebfa52030d5c 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c | |||
@@ -67,22 +67,21 @@ static int mmap_is_legacy(void) | |||
67 | 67 | ||
68 | static unsigned long mmap_rnd(void) | 68 | static unsigned long mmap_rnd(void) |
69 | { | 69 | { |
70 | unsigned long rnd = 0; | 70 | unsigned long rnd; |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * 8 bits of randomness in 32bit mmaps, 20 address space bits | 73 | * 8 bits of randomness in 32bit mmaps, 20 address space bits |
74 | * 28 bits of randomness in 64bit mmaps, 40 address space bits | 74 | * 28 bits of randomness in 64bit mmaps, 40 address space bits |
75 | */ | 75 | */ |
76 | if (current->flags & PF_RANDOMIZE) { | 76 | if (mmap_is_ia32()) |
77 | if (mmap_is_ia32()) | 77 | rnd = (unsigned long)get_random_int() % (1<<8); |
78 | rnd = get_random_int() % (1<<8); | 78 | else |
79 | else | 79 | rnd = (unsigned long)get_random_int() % (1<<28); |
80 | rnd = get_random_int() % (1<<28); | 80 | |
81 | } | ||
82 | return rnd << PAGE_SHIFT; | 81 | return rnd << PAGE_SHIFT; |
83 | } | 82 | } |
84 | 83 | ||
85 | static unsigned long mmap_base(void) | 84 | static unsigned long mmap_base(unsigned long rnd) |
86 | { | 85 | { |
87 | unsigned long gap = rlimit(RLIMIT_STACK); | 86 | unsigned long gap = rlimit(RLIMIT_STACK); |
88 | 87 | ||
@@ -91,19 +90,19 @@ static unsigned long mmap_base(void) | |||
91 | else if (gap > MAX_GAP) | 90 | else if (gap > MAX_GAP) |
92 | gap = MAX_GAP; | 91 | gap = MAX_GAP; |
93 | 92 | ||
94 | return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd()); | 93 | return PAGE_ALIGN(TASK_SIZE - gap - rnd); |
95 | } | 94 | } |
96 | 95 | ||
97 | /* | 96 | /* |
98 | * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 | 97 | * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 |
99 | * does, but not when emulating X86_32 | 98 | * does, but not when emulating X86_32 |
100 | */ | 99 | */ |
101 | static unsigned long mmap_legacy_base(void) | 100 | static unsigned long mmap_legacy_base(unsigned long rnd) |
102 | { | 101 | { |
103 | if (mmap_is_ia32()) | 102 | if (mmap_is_ia32()) |
104 | return TASK_UNMAPPED_BASE; | 103 | return TASK_UNMAPPED_BASE; |
105 | else | 104 | else |
106 | return TASK_UNMAPPED_BASE + mmap_rnd(); | 105 | return TASK_UNMAPPED_BASE + rnd; |
107 | } | 106 | } |
108 | 107 | ||
109 | /* | 108 | /* |
@@ -112,13 +111,18 @@ static unsigned long mmap_legacy_base(void) | |||
112 | */ | 111 | */ |
113 | void arch_pick_mmap_layout(struct mm_struct *mm) | 112 | void arch_pick_mmap_layout(struct mm_struct *mm) |
114 | { | 113 | { |
115 | mm->mmap_legacy_base = mmap_legacy_base(); | 114 | unsigned long random_factor = 0UL; |
116 | mm->mmap_base = mmap_base(); | 115 | |
116 | if (current->flags & PF_RANDOMIZE) | ||
117 | random_factor = mmap_rnd(); | ||
118 | |||
119 | mm->mmap_legacy_base = mmap_legacy_base(random_factor); | ||
117 | 120 | ||
118 | if (mmap_is_legacy()) { | 121 | if (mmap_is_legacy()) { |
119 | mm->mmap_base = mm->mmap_legacy_base; | 122 | mm->mmap_base = mm->mmap_legacy_base; |
120 | mm->get_unmapped_area = arch_get_unmapped_area; | 123 | mm->get_unmapped_area = arch_get_unmapped_area; |
121 | } else { | 124 | } else { |
125 | mm->mmap_base = mmap_base(random_factor); | ||
122 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; | 126 | mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
123 | } | 127 | } |
124 | } | 128 | } |