diff options
Diffstat (limited to 'kernel/ptrace.c')
| -rw-r--r-- | kernel/ptrace.c | 55 |
1 files changed, 1 insertions, 54 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 9a111f70145c..4d50e06fd745 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -241,60 +241,6 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
| 241 | return 0; | 241 | return 0; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | /* | ||
| 245 | * Access another process' address space. | ||
| 246 | * Source/target buffer must be kernel space, | ||
| 247 | * Do not walk the page table directly, use get_user_pages | ||
| 248 | */ | ||
| 249 | |||
| 250 | int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write) | ||
| 251 | { | ||
| 252 | struct mm_struct *mm; | ||
| 253 | struct vm_area_struct *vma; | ||
| 254 | struct page *page; | ||
| 255 | void *old_buf = buf; | ||
| 256 | |||
| 257 | mm = get_task_mm(tsk); | ||
| 258 | if (!mm) | ||
| 259 | return 0; | ||
| 260 | |||
| 261 | down_read(&mm->mmap_sem); | ||
| 262 | /* ignore errors, just check how much was sucessfully transfered */ | ||
| 263 | while (len) { | ||
| 264 | int bytes, ret, offset; | ||
| 265 | void *maddr; | ||
| 266 | |||
| 267 | ret = get_user_pages(tsk, mm, addr, 1, | ||
| 268 | write, 1, &page, &vma); | ||
| 269 | if (ret <= 0) | ||
| 270 | break; | ||
| 271 | |||
| 272 | bytes = len; | ||
| 273 | offset = addr & (PAGE_SIZE-1); | ||
| 274 | if (bytes > PAGE_SIZE-offset) | ||
| 275 | bytes = PAGE_SIZE-offset; | ||
| 276 | |||
| 277 | maddr = kmap(page); | ||
| 278 | if (write) { | ||
| 279 | copy_to_user_page(vma, page, addr, | ||
| 280 | maddr + offset, buf, bytes); | ||
| 281 | set_page_dirty_lock(page); | ||
| 282 | } else { | ||
| 283 | copy_from_user_page(vma, page, addr, | ||
| 284 | buf, maddr + offset, bytes); | ||
| 285 | } | ||
| 286 | kunmap(page); | ||
| 287 | page_cache_release(page); | ||
| 288 | len -= bytes; | ||
| 289 | buf += bytes; | ||
| 290 | addr += bytes; | ||
| 291 | } | ||
| 292 | up_read(&mm->mmap_sem); | ||
| 293 | mmput(mm); | ||
| 294 | |||
| 295 | return buf - old_buf; | ||
| 296 | } | ||
| 297 | |||
| 298 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) | 244 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) |
| 299 | { | 245 | { |
| 300 | int copied = 0; | 246 | int copied = 0; |
| @@ -494,6 +440,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) | |||
| 494 | child = find_task_by_pid(pid); | 440 | child = find_task_by_pid(pid); |
| 495 | if (child) | 441 | if (child) |
| 496 | get_task_struct(child); | 442 | get_task_struct(child); |
| 443 | |||
| 497 | read_unlock(&tasklist_lock); | 444 | read_unlock(&tasklist_lock); |
| 498 | if (!child) | 445 | if (!child) |
| 499 | return ERR_PTR(-ESRCH); | 446 | return ERR_PTR(-ESRCH); |
