mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
posix-cpu-timers: Fix nanosleep task_struct leak
The trinity fuzzer triggered a task_struct reference leak via clock_nanosleep with CPU_TIMERs. do_cpu_nanosleep() calls posic_cpu_timer_create(), but misses a corresponding posix_cpu_timer_del() which leads to the task_struct reference leak. Reported-and-tested-by: Tommi Rantala <tt.rantala@gmail.com> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Cc: Dave Jones <davej@redhat.com> Cc: John Stultz <john.stultz@linaro.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20130215100810.GF4392@redhat.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
9f4646d283
commit
e6c42c295e
@ -1401,8 +1401,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
||||
while (!signal_pending(current)) {
|
||||
if (timer.it.cpu.expires.sched == 0) {
|
||||
/*
|
||||
* Our timer fired and was reset.
|
||||
* Our timer fired and was reset, below
|
||||
* deletion can not fail.
|
||||
*/
|
||||
posix_cpu_timer_del(&timer);
|
||||
spin_unlock_irq(&timer.it_lock);
|
||||
return 0;
|
||||
}
|
||||
@ -1420,9 +1422,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
||||
* We were interrupted by a signal.
|
||||
*/
|
||||
sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
|
||||
posix_cpu_timer_set(&timer, 0, &zero_it, it);
|
||||
error = posix_cpu_timer_set(&timer, 0, &zero_it, it);
|
||||
if (!error) {
|
||||
/*
|
||||
* Timer is now unarmed, deletion can not fail.
|
||||
*/
|
||||
posix_cpu_timer_del(&timer);
|
||||
}
|
||||
spin_unlock_irq(&timer.it_lock);
|
||||
|
||||
while (error == TIMER_RETRY) {
|
||||
/*
|
||||
* We need to handle case when timer was or is in the
|
||||
* middle of firing. In other cases we already freed
|
||||
* resources.
|
||||
*/
|
||||
spin_lock_irq(&timer.it_lock);
|
||||
error = posix_cpu_timer_del(&timer);
|
||||
spin_unlock_irq(&timer.it_lock);
|
||||
}
|
||||
|
||||
if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
|
||||
/*
|
||||
* It actually did fire already.
|
||||
|
Loading…
Reference in New Issue
Block a user