mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
posix-cpu-timers: Fix nanosleep task_struct leak
commit e6c42c295e
upstream.
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>
Link: http://lkml.kernel.org/r/20130215100810.GF4392@redhat.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b3c57f009c
commit
7c3e516d99
1 changed files with 21 additions and 2 deletions
|
@ -1422,8 +1422,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
||||||
while (!signal_pending(current)) {
|
while (!signal_pending(current)) {
|
||||||
if (timer.it.cpu.expires.sched == 0) {
|
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);
|
spin_unlock_irq(&timer.it_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1441,9 +1443,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
||||||
* We were interrupted by a signal.
|
* We were interrupted by a signal.
|
||||||
*/
|
*/
|
||||||
sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
|
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);
|
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) {
|
if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) {
|
||||||
/*
|
/*
|
||||||
* It actually did fire already.
|
* It actually did fire already.
|
||||||
|
|
Loading…
Reference in a new issue