Commit 1b108956 authored by Al Viro's avatar Al Viro

mISDN: fix races between misdn_del_timer() and timer callback

mark the victim with negative ->id if misdn_del_timer() finds it on
the list, have timer callback *not* move ones so marked to dev->expired
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c08c464d
...@@ -163,7 +163,8 @@ dev_expire_timer(unsigned long data) ...@@ -163,7 +163,8 @@ dev_expire_timer(unsigned long data)
u_long flags; u_long flags;
spin_lock_irqsave(&timer->dev->lock, flags); spin_lock_irqsave(&timer->dev->lock, flags);
list_move_tail(&timer->list, &timer->dev->expired); if (timer->id >= 0)
list_move_tail(&timer->list, &timer->dev->expired);
spin_unlock_irqrestore(&timer->dev->lock, flags); spin_unlock_irqrestore(&timer->dev->lock, flags);
wake_up_interruptible(&timer->dev->wait); wake_up_interruptible(&timer->dev->wait);
} }
...@@ -203,26 +204,21 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) ...@@ -203,26 +204,21 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
static int static int
misdn_del_timer(struct mISDNtimerdev *dev, int id) misdn_del_timer(struct mISDNtimerdev *dev, int id)
{ {
u_long flags;
struct mISDNtimer *timer; struct mISDNtimer *timer;
int ret = 0;
spin_lock_irqsave(&dev->lock, flags); spin_lock_irq(&dev->lock);
list_for_each_entry(timer, &dev->pending, list) { list_for_each_entry(timer, &dev->pending, list) {
if (timer->id == id) { if (timer->id == id) {
list_del_init(&timer->list); list_del_init(&timer->list);
/* RED-PEN AK: race -- timer can be still running on timer->id = -1;
* other CPU. Needs reference count I think spin_unlock_irq(&dev->lock);
*/ del_timer_sync(&timer->tl);
del_timer(&timer->tl);
ret = timer->id;
kfree(timer); kfree(timer);
goto unlock; return id;
} }
} }
unlock: spin_unlock_irq(&dev->lock);
spin_unlock_irqrestore(&dev->lock, flags); return 0;
return ret;
} }
static long static long
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment