mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Bluetooth: L2CAP: make concurrent l2cap_set_timer() refcounting safe
Since l2cap_set_timer() does not check return value of schedule_delayed_work(), two concurrent calls may result to l2cap_chan refcount leak. Change the refcounting by using mod_delayed_work() and checking its return value. Code paths aside from l2cap_chan_busy() hold chan->lock, so this has little correctness impact. Signed-off-by: Pauli Virtanen <pav@iki.fi> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
b508a2a2d8
commit
aba67d585b
|
|
@ -847,12 +847,11 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
|
|||
BT_DBG("chan %p state %s timeout %ld", chan,
|
||||
state_to_string(chan->state), timeout);
|
||||
|
||||
/* If delayed work cancelled do not hold(chan)
|
||||
since it is already done with previous set_timer */
|
||||
if (!cancel_delayed_work(work))
|
||||
l2cap_chan_hold(chan);
|
||||
l2cap_chan_hold(chan);
|
||||
|
||||
schedule_delayed_work(work, timeout);
|
||||
/* put(chan) if timer was already queued so it already has a ref */
|
||||
if (mod_delayed_work(system_percpu_wq, work, timeout))
|
||||
l2cap_chan_put(chan);
|
||||
}
|
||||
|
||||
static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user