diff options
Diffstat (limited to 'kernel/ptrace.c')
| -rw-r--r-- | kernel/ptrace.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index aaad0ec34194..0692ab5a0d67 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
| @@ -21,9 +21,7 @@ | |||
| 21 | #include <linux/audit.h> | 21 | #include <linux/audit.h> |
| 22 | #include <linux/pid_namespace.h> | 22 | #include <linux/pid_namespace.h> |
| 23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
| 24 | 24 | #include <linux/uaccess.h> | |
| 25 | #include <asm/pgtable.h> | ||
| 26 | #include <asm/uaccess.h> | ||
| 27 | 25 | ||
| 28 | 26 | ||
| 29 | /* | 27 | /* |
| @@ -48,7 +46,7 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) | |||
| 48 | list_add(&child->ptrace_entry, &new_parent->ptraced); | 46 | list_add(&child->ptrace_entry, &new_parent->ptraced); |
| 49 | child->parent = new_parent; | 47 | child->parent = new_parent; |
| 50 | } | 48 | } |
| 51 | 49 | ||
| 52 | /* | 50 | /* |
| 53 | * Turn a tracing stop into a normal stop now, since with no tracer there | 51 | * Turn a tracing stop into a normal stop now, since with no tracer there |
| 54 | * would be no way to wake it up with SIGCONT or SIGKILL. If there was a | 52 | * would be no way to wake it up with SIGCONT or SIGKILL. If there was a |
| @@ -173,7 +171,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) | |||
| 173 | task_lock(task); | 171 | task_lock(task); |
| 174 | err = __ptrace_may_access(task, mode); | 172 | err = __ptrace_may_access(task, mode); |
| 175 | task_unlock(task); | 173 | task_unlock(task); |
| 176 | return (!err ? true : false); | 174 | return !err; |
| 177 | } | 175 | } |
| 178 | 176 | ||
| 179 | int ptrace_attach(struct task_struct *task) | 177 | int ptrace_attach(struct task_struct *task) |
| @@ -190,7 +188,7 @@ int ptrace_attach(struct task_struct *task) | |||
| 190 | /* Protect exec's credential calculations against our interference; | 188 | /* Protect exec's credential calculations against our interference; |
| 191 | * SUID, SGID and LSM creds get determined differently under ptrace. | 189 | * SUID, SGID and LSM creds get determined differently under ptrace. |
| 192 | */ | 190 | */ |
| 193 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | 191 | retval = mutex_lock_interruptible(&task->cred_exec_mutex); |
| 194 | if (retval < 0) | 192 | if (retval < 0) |
| 195 | goto out; | 193 | goto out; |
| 196 | 194 | ||
| @@ -234,7 +232,7 @@ repeat: | |||
| 234 | bad: | 232 | bad: |
| 235 | write_unlock_irqrestore(&tasklist_lock, flags); | 233 | write_unlock_irqrestore(&tasklist_lock, flags); |
| 236 | task_unlock(task); | 234 | task_unlock(task); |
| 237 | mutex_unlock(¤t->cred_exec_mutex); | 235 | mutex_unlock(&task->cred_exec_mutex); |
| 238 | out: | 236 | out: |
| 239 | return retval; | 237 | return retval; |
| 240 | } | 238 | } |
| @@ -358,7 +356,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst | |||
| 358 | copied += retval; | 356 | copied += retval; |
| 359 | src += retval; | 357 | src += retval; |
| 360 | dst += retval; | 358 | dst += retval; |
| 361 | len -= retval; | 359 | len -= retval; |
| 362 | } | 360 | } |
| 363 | return copied; | 361 | return copied; |
| 364 | } | 362 | } |
| @@ -383,7 +381,7 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds | |||
| 383 | copied += retval; | 381 | copied += retval; |
| 384 | src += retval; | 382 | src += retval; |
| 385 | dst += retval; | 383 | dst += retval; |
| 386 | len -= retval; | 384 | len -= retval; |
| 387 | } | 385 | } |
| 388 | return copied; | 386 | return copied; |
| 389 | } | 387 | } |
| @@ -496,9 +494,9 @@ static int ptrace_resume(struct task_struct *child, long request, long data) | |||
| 496 | if (unlikely(!arch_has_single_step())) | 494 | if (unlikely(!arch_has_single_step())) |
| 497 | return -EIO; | 495 | return -EIO; |
| 498 | user_enable_single_step(child); | 496 | user_enable_single_step(child); |
| 499 | } | 497 | } else { |
| 500 | else | ||
| 501 | user_disable_single_step(child); | 498 | user_disable_single_step(child); |
| 499 | } | ||
| 502 | 500 | ||
| 503 | child->exit_code = data; | 501 | child->exit_code = data; |
| 504 | wake_up_process(child); | 502 | wake_up_process(child); |
| @@ -606,10 +604,11 @@ repeat: | |||
| 606 | ret = security_ptrace_traceme(current->parent); | 604 | ret = security_ptrace_traceme(current->parent); |
| 607 | 605 | ||
| 608 | /* | 606 | /* |
| 609 | * Set the ptrace bit in the process ptrace flags. | 607 | * Check PF_EXITING to ensure ->real_parent has not passed |
| 610 | * Then link us on our parent's ptraced list. | 608 | * exit_ptrace(). Otherwise we don't report the error but |
| 609 | * pretend ->real_parent untraces us right after return. | ||
| 611 | */ | 610 | */ |
| 612 | if (!ret) { | 611 | if (!ret && !(current->real_parent->flags & PF_EXITING)) { |
| 613 | current->ptrace |= PT_PTRACED; | 612 | current->ptrace |= PT_PTRACED; |
| 614 | __ptrace_link(current, current->real_parent); | 613 | __ptrace_link(current, current->real_parent); |
| 615 | } | 614 | } |
