diff options
Diffstat (limited to 'arch/mips/kernel/syscall.c')
-rw-r--r-- | arch/mips/kernel/syscall.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index dd81b0f87518..bddce0bca195 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/ipc.h> | 29 | #include <linux/ipc.h> |
30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/random.h> | ||
33 | #include <linux/elf.h> | ||
32 | 34 | ||
33 | #include <asm/asm.h> | 35 | #include <asm/asm.h> |
34 | #include <asm/branch.h> | 36 | #include <asm/branch.h> |
@@ -116,7 +118,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
116 | (!vmm || addr + len <= vmm->vm_start)) | 118 | (!vmm || addr + len <= vmm->vm_start)) |
117 | return addr; | 119 | return addr; |
118 | } | 120 | } |
119 | addr = TASK_UNMAPPED_BASE; | 121 | addr = current->mm->mmap_base; |
120 | if (do_color_align) | 122 | if (do_color_align) |
121 | addr = COLOUR_ALIGN(addr, pgoff); | 123 | addr = COLOUR_ALIGN(addr, pgoff); |
122 | else | 124 | else |
@@ -134,6 +136,51 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
134 | } | 136 | } |
135 | } | 137 | } |
136 | 138 | ||
139 | void arch_pick_mmap_layout(struct mm_struct *mm) | ||
140 | { | ||
141 | unsigned long random_factor = 0UL; | ||
142 | |||
143 | if (current->flags & PF_RANDOMIZE) { | ||
144 | random_factor = get_random_int(); | ||
145 | random_factor = random_factor << PAGE_SHIFT; | ||
146 | if (TASK_IS_32BIT_ADDR) | ||
147 | random_factor &= 0xfffffful; | ||
148 | else | ||
149 | random_factor &= 0xffffffful; | ||
150 | } | ||
151 | |||
152 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; | ||
153 | mm->get_unmapped_area = arch_get_unmapped_area; | ||
154 | mm->unmap_area = arch_unmap_area; | ||
155 | } | ||
156 | |||
157 | static inline unsigned long brk_rnd(void) | ||
158 | { | ||
159 | unsigned long rnd = get_random_int(); | ||
160 | |||
161 | rnd = rnd << PAGE_SHIFT; | ||
162 | /* 8MB for 32bit, 256MB for 64bit */ | ||
163 | if (TASK_IS_32BIT_ADDR) | ||
164 | rnd = rnd & 0x7ffffful; | ||
165 | else | ||
166 | rnd = rnd & 0xffffffful; | ||
167 | |||
168 | return rnd; | ||
169 | } | ||
170 | |||
171 | unsigned long arch_randomize_brk(struct mm_struct *mm) | ||
172 | { | ||
173 | unsigned long base = mm->brk; | ||
174 | unsigned long ret; | ||
175 | |||
176 | ret = PAGE_ALIGN(base + brk_rnd()); | ||
177 | |||
178 | if (ret < mm->brk) | ||
179 | return mm->brk; | ||
180 | |||
181 | return ret; | ||
182 | } | ||
183 | |||
137 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, | 184 | SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len, |
138 | unsigned long, prot, unsigned long, flags, unsigned long, | 185 | unsigned long, prot, unsigned long, flags, unsigned long, |
139 | fd, off_t, offset) | 186 | fd, off_t, offset) |
@@ -207,7 +254,7 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) | |||
207 | int error; | 254 | int error; |
208 | char * filename; | 255 | char * filename; |
209 | 256 | ||
210 | filename = getname((char __user *) (long)regs.regs[4]); | 257 | filename = getname((const char __user *) (long)regs.regs[4]); |
211 | error = PTR_ERR(filename); | 258 | error = PTR_ERR(filename); |
212 | if (IS_ERR(filename)) | 259 | if (IS_ERR(filename)) |
213 | goto out; | 260 | goto out; |