diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-17 11:23:24 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-17 11:23:24 +0200 |
| commit | a954e5fb4bc2d401b8fc3b4c7cd316497ff80225 (patch) | |
| tree | 06af23b232c7c2e795a2fef8a5a0604ec64d5092 /kernel/ptrace.c | |
| parent | e137d34f94ebcb6508d7c8614ac045583fffbe2a (diff) | |
| parent | 9e0babf2c06c73cda2c0cd37a1653d823adb40ec (diff) | |
Merge 5.2-rc5 into usb-next
We need the USB fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/ptrace.c')
| -rw-r--r-- | kernel/ptrace.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 5710d07e67cf..8456b6e2205f 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -324,6 +324,16 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode) return -EPERM; ok: rcu_read_unlock(); + /* + * If a task drops privileges and becomes nondumpable (through a syscall + * like setresuid()) while we are trying to access it, we must ensure + * that the dumpability is read after the credentials; otherwise, + * we may be able to attach to a task that we shouldn't be able to + * attach to (as if the task had dropped privileges without becoming + * nondumpable). + * Pairs with a write barrier in commit_creds(). + */ + smp_rmb(); mm = task->mm; if (mm && ((get_dumpable(mm) != SUID_DUMP_USER) && @@ -705,6 +715,10 @@ static int ptrace_peek_siginfo(struct task_struct *child, if (arg.nr < 0) return -EINVAL; + /* Ensure arg.off fits in an unsigned long */ + if (arg.off > ULONG_MAX) + return 0; + if (arg.flags & PTRACE_PEEKSIGINFO_SHARED) pending = &child->signal->shared_pending; else @@ -712,18 +726,20 @@ static int ptrace_peek_siginfo(struct task_struct *child, for (i = 0; i < arg.nr; ) { kernel_siginfo_t info; - s32 off = arg.off + i; + unsigned long off = arg.off + i; + bool found = false; spin_lock_irq(&child->sighand->siglock); list_for_each_entry(q, &pending->list, list) { if (!off--) { + found = true; copy_siginfo(&info, &q->info); break; } } spin_unlock_irq(&child->sighand->siglock); - if (off >= 0) /* beyond the end of the list */ + if (!found) /* beyond the end of the list */ break; #ifdef CONFIG_COMPAT |
