diff options
-rw-r--r-- | kernel/ptrace.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 6f357f4fc859..02c6528ead5c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -704,6 +704,10 @@ static int ptrace_peek_siginfo(struct task_struct *child, | |||
704 | if (arg.nr < 0) | 704 | if (arg.nr < 0) |
705 | return -EINVAL; | 705 | return -EINVAL; |
706 | 706 | ||
707 | /* Ensure arg.off fits in an unsigned long */ | ||
708 | if (arg.off > ULONG_MAX) | ||
709 | return 0; | ||
710 | |||
707 | if (arg.flags & PTRACE_PEEKSIGINFO_SHARED) | 711 | if (arg.flags & PTRACE_PEEKSIGINFO_SHARED) |
708 | pending = &child->signal->shared_pending; | 712 | pending = &child->signal->shared_pending; |
709 | else | 713 | else |
@@ -711,18 +715,20 @@ static int ptrace_peek_siginfo(struct task_struct *child, | |||
711 | 715 | ||
712 | for (i = 0; i < arg.nr; ) { | 716 | for (i = 0; i < arg.nr; ) { |
713 | kernel_siginfo_t info; | 717 | kernel_siginfo_t info; |
714 | s32 off = arg.off + i; | 718 | unsigned long off = arg.off + i; |
719 | bool found = false; | ||
715 | 720 | ||
716 | spin_lock_irq(&child->sighand->siglock); | 721 | spin_lock_irq(&child->sighand->siglock); |
717 | list_for_each_entry(q, &pending->list, list) { | 722 | list_for_each_entry(q, &pending->list, list) { |
718 | if (!off--) { | 723 | if (!off--) { |
724 | found = true; | ||
719 | copy_siginfo(&info, &q->info); | 725 | copy_siginfo(&info, &q->info); |
720 | break; | 726 | break; |
721 | } | 727 | } |
722 | } | 728 | } |
723 | spin_unlock_irq(&child->sighand->siglock); | 729 | spin_unlock_irq(&child->sighand->siglock); |
724 | 730 | ||
725 | if (off >= 0) /* beyond the end of the list */ | 731 | if (!found) /* beyond the end of the list */ |
726 | break; | 732 | break; |
727 | 733 | ||
728 | #ifdef CONFIG_COMPAT | 734 | #ifdef CONFIG_COMPAT |