mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
[PATCH] ITIMER_REAL: fix possible deadlock and race
As Steven Rostedt pointed out, there are 2 problems with ITIMER_REAL timers. 1. do_setitimer() does not call del_timer_sync() in case when the timer is not pending (it_real_value() returns 0). This is wrong, the timer may still be running, and it can rearm itself. 2. It calls del_timer_sync() with tsk->sighand->siglock held. This is deadlockable, because timer's handler needs this lock too. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Acked-by: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
b36bbb6c3d
commit
f01b1b0baa
@ -153,11 +153,15 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
|
||||
|
||||
switch (which) {
|
||||
case ITIMER_REAL:
|
||||
again:
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
interval = tsk->signal->it_real_incr;
|
||||
val = it_real_value(tsk->signal);
|
||||
if (val)
|
||||
del_timer_sync(&tsk->signal->real_timer);
|
||||
/* We are sharing ->siglock with it_real_fn() */
|
||||
if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
goto again;
|
||||
}
|
||||
tsk->signal->it_real_incr =
|
||||
timeval_to_jiffies(&value->it_interval);
|
||||
it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
|
||||
|
Loading…
Reference in New Issue
Block a user