diff options
Diffstat (limited to 'kernel/ptrace.c')
| -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,  	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 @@ -711,18 +715,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  | 
