diff options
author | Mike Frysinger <vapier.adi@gmail.com> | 2008-10-10 05:26:57 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-10-10 05:26:57 -0400 |
commit | d207a8c7681f14302e9e80ef5b8202abe39060b5 (patch) | |
tree | baed22d2c9151866d4b5a591408349fb35d73fb9 /arch/blackfin | |
parent | 2043f3f7312cc7fbbc2acffb9d87265b0ad9a529 (diff) |
Blackfin arch: ptrace - fix off-by-one check on end of memory regions
Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index e8172eece047..7e1f762b6700 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -161,15 +161,15 @@ static inline int is_user_addr_valid(struct task_struct *child, | |||
161 | struct sram_list_struct *sraml; | 161 | struct sram_list_struct *sraml; |
162 | 162 | ||
163 | for (vml = child->mm->context.vmlist; vml; vml = vml->next) | 163 | for (vml = child->mm->context.vmlist; vml; vml = vml->next) |
164 | if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end) | 164 | if (start >= vml->vma->vm_start && start + len < vml->vma->vm_end) |
165 | return 0; | 165 | return 0; |
166 | 166 | ||
167 | for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next) | 167 | for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next) |
168 | if (start >= (unsigned long)sraml->addr | 168 | if (start >= (unsigned long)sraml->addr |
169 | && start + len <= (unsigned long)sraml->addr + sraml->length) | 169 | && start + len < (unsigned long)sraml->addr + sraml->length) |
170 | return 0; | 170 | return 0; |
171 | 171 | ||
172 | if (start >= FIXED_CODE_START && start + len <= FIXED_CODE_END) | 172 | if (start >= FIXED_CODE_START && start + len < FIXED_CODE_END) |
173 | return 0; | 173 | return 0; |
174 | 174 | ||
175 | return -EIO; | 175 | return -EIO; |
@@ -216,34 +216,30 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
216 | break; | 216 | break; |
217 | pr_debug("ptrace: user address is valid\n"); | 217 | pr_debug("ptrace: user address is valid\n"); |
218 | 218 | ||
219 | #if L1_CODE_LENGTH != 0 | 219 | if (L1_CODE_LENGTH != 0 && addr >= L1_CODE_START |
220 | if (addr >= L1_CODE_START | ||
221 | && addr + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { | 220 | && addr + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { |
222 | safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); | 221 | safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); |
223 | copied = sizeof(tmp); | 222 | copied = sizeof(tmp); |
224 | } else | 223 | |
225 | #endif | 224 | } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START |
226 | #if L1_DATA_A_LENGTH != 0 | ||
227 | if (addr >= L1_DATA_A_START | ||
228 | && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | 225 | && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { |
229 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); | 226 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
230 | copied = sizeof(tmp); | 227 | copied = sizeof(tmp); |
231 | } else | 228 | |
232 | #endif | 229 | } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START |
233 | #if L1_DATA_B_LENGTH != 0 | ||
234 | if (addr >= L1_DATA_B_START | ||
235 | && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | 230 | && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { |
236 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); | 231 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
237 | copied = sizeof(tmp); | 232 | copied = sizeof(tmp); |
238 | } else | 233 | |
239 | #endif | 234 | } else if (addr >= FIXED_CODE_START |
240 | if (addr >= FIXED_CODE_START | ||
241 | && addr + sizeof(tmp) <= FIXED_CODE_END) { | 235 | && addr + sizeof(tmp) <= FIXED_CODE_END) { |
242 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); | 236 | memcpy(&tmp, (const void *)(addr), sizeof(tmp)); |
243 | copied = sizeof(tmp); | 237 | copied = sizeof(tmp); |
238 | |||
244 | } else | 239 | } else |
245 | copied = access_process_vm(child, addr, &tmp, | 240 | copied = access_process_vm(child, addr, &tmp, |
246 | sizeof(tmp), 0); | 241 | sizeof(tmp), 0); |
242 | |||
247 | pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); | 243 | pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); |
248 | if (copied != sizeof(tmp)) | 244 | if (copied != sizeof(tmp)) |
249 | break; | 245 | break; |
@@ -300,34 +296,30 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
300 | break; | 296 | break; |
301 | pr_debug("ptrace: user address is valid\n"); | 297 | pr_debug("ptrace: user address is valid\n"); |
302 | 298 | ||
303 | #if L1_CODE_LENGTH != 0 | 299 | if (L1_CODE_LENGTH != 0 && addr >= L1_CODE_START |
304 | if (addr >= L1_CODE_START | ||
305 | && addr + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { | 300 | && addr + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { |
306 | safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); | 301 | safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); |
307 | copied = sizeof(data); | 302 | copied = sizeof(data); |
308 | } else | 303 | |
309 | #endif | 304 | } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START |
310 | #if L1_DATA_A_LENGTH != 0 | ||
311 | if (addr >= L1_DATA_A_START | ||
312 | && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | 305 | && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { |
313 | memcpy((void *)(addr), &data, sizeof(data)); | 306 | memcpy((void *)(addr), &data, sizeof(data)); |
314 | copied = sizeof(data); | 307 | copied = sizeof(data); |
315 | } else | 308 | |
316 | #endif | 309 | } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START |
317 | #if L1_DATA_B_LENGTH != 0 | ||
318 | if (addr >= L1_DATA_B_START | ||
319 | && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | 310 | && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { |
320 | memcpy((void *)(addr), &data, sizeof(data)); | 311 | memcpy((void *)(addr), &data, sizeof(data)); |
321 | copied = sizeof(data); | 312 | copied = sizeof(data); |
322 | } else | 313 | |
323 | #endif | 314 | } else if (addr >= FIXED_CODE_START |
324 | if (addr >= FIXED_CODE_START | ||
325 | && addr + sizeof(data) <= FIXED_CODE_END) { | 315 | && addr + sizeof(data) <= FIXED_CODE_END) { |
326 | memcpy((void *)(addr), &data, sizeof(data)); | 316 | memcpy((void *)(addr), &data, sizeof(data)); |
327 | copied = sizeof(data); | 317 | copied = sizeof(data); |
318 | |||
328 | } else | 319 | } else |
329 | copied = access_process_vm(child, addr, &data, | 320 | copied = access_process_vm(child, addr, &data, |
330 | sizeof(data), 1); | 321 | sizeof(data), 1); |
322 | |||
331 | pr_debug("ptrace: copied size %d\n", copied); | 323 | pr_debug("ptrace: copied size %d\n", copied); |
332 | if (copied != sizeof(data)) | 324 | if (copied != sizeof(data)) |
333 | break; | 325 | break; |