diff options
Diffstat (limited to 'kernel/ptrace.c')
| -rw-r--r-- | kernel/ptrace.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 5f33cdb6fff5..d95a72c9279d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -72,8 +72,8 @@ void ptrace_untrace(task_t *child) | |||
| 72 | */ | 72 | */ |
| 73 | void __ptrace_unlink(task_t *child) | 73 | void __ptrace_unlink(task_t *child) |
| 74 | { | 74 | { |
| 75 | if (!child->ptrace) | 75 | BUG_ON(!child->ptrace); |
| 76 | BUG(); | 76 | |
| 77 | child->ptrace = 0; | 77 | child->ptrace = 0; |
| 78 | if (!list_empty(&child->ptrace_list)) { | 78 | if (!list_empty(&child->ptrace_list)) { |
| 79 | list_del_init(&child->ptrace_list); | 79 | list_del_init(&child->ptrace_list); |
| @@ -184,22 +184,27 @@ bad: | |||
| 184 | return retval; | 184 | return retval; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | void __ptrace_detach(struct task_struct *child, unsigned int data) | ||
| 188 | { | ||
| 189 | child->exit_code = data; | ||
| 190 | /* .. re-parent .. */ | ||
| 191 | __ptrace_unlink(child); | ||
| 192 | /* .. and wake it up. */ | ||
| 193 | if (child->exit_state != EXIT_ZOMBIE) | ||
| 194 | wake_up_process(child); | ||
| 195 | } | ||
| 196 | |||
| 187 | int ptrace_detach(struct task_struct *child, unsigned int data) | 197 | int ptrace_detach(struct task_struct *child, unsigned int data) |
| 188 | { | 198 | { |
| 189 | if (!valid_signal(data)) | 199 | if (!valid_signal(data)) |
| 190 | return -EIO; | 200 | return -EIO; |
| 191 | 201 | ||
| 192 | /* Architecture-specific hardware disable .. */ | 202 | /* Architecture-specific hardware disable .. */ |
| 193 | ptrace_disable(child); | 203 | ptrace_disable(child); |
| 194 | 204 | ||
| 195 | /* .. re-parent .. */ | ||
| 196 | child->exit_code = data; | ||
| 197 | |||
| 198 | write_lock_irq(&tasklist_lock); | 205 | write_lock_irq(&tasklist_lock); |
| 199 | __ptrace_unlink(child); | 206 | if (child->ptrace) |
| 200 | /* .. and wake it up. */ | 207 | __ptrace_detach(child, data); |
| 201 | if (child->exit_state != EXIT_ZOMBIE) | ||
| 202 | wake_up_process(child); | ||
| 203 | write_unlock_irq(&tasklist_lock); | 208 | write_unlock_irq(&tasklist_lock); |
| 204 | 209 | ||
| 205 | return 0; | 210 | return 0; |
| @@ -242,8 +247,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in | |||
| 242 | if (write) { | 247 | if (write) { |
| 243 | copy_to_user_page(vma, page, addr, | 248 | copy_to_user_page(vma, page, addr, |
| 244 | maddr + offset, buf, bytes); | 249 | maddr + offset, buf, bytes); |
| 245 | if (!PageCompound(page)) | 250 | set_page_dirty_lock(page); |
| 246 | set_page_dirty_lock(page); | ||
| 247 | } else { | 251 | } else { |
| 248 | copy_from_user_page(vma, page, addr, | 252 | copy_from_user_page(vma, page, addr, |
| 249 | buf, maddr + offset, bytes); | 253 | buf, maddr + offset, bytes); |
