* [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work()
@ 2012-01-30 20:26 Ulisses Furquim
2012-01-30 20:26 ` [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path Ulisses Furquim
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Ulisses Furquim @ 2012-01-30 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan
__cancel_delayed_work() is being used in some paths where we cannot
sleep waiting for the delayed work to finish. However, that function
might return while the timer is running and the work will be queued
again. Replace the calls with safer cancel_delayed_work() version
which spins until the timer handler finishes on other CPUs and
cancels the delayed work.
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
---
include/net/bluetooth/l2cap.h | 4 ++--
net/bluetooth/l2cap_core.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e7a8cc7..42fdbb8 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -614,7 +614,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
- if (!__cancel_delayed_work(work))
+ if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
@@ -624,7 +624,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
{
bool ret;
- ret = __cancel_delayed_work(work);
+ ret = cancel_delayed_work(work);
if (ret)
l2cap_chan_put(chan);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 942ba1d..ae7fb27 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2588,7 +2588,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) {
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
@@ -3135,7 +3135,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0;
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4509,7 +4509,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0);
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();
--
1.7.8.rc4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path 2012-01-30 20:26 [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim @ 2012-01-30 20:26 ` Ulisses Furquim 2012-01-30 21:30 ` Marcel Holtmann 2012-01-30 21:29 ` [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Marcel Holtmann ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Ulisses Furquim @ 2012-01-30 20:26 UTC (permalink / raw) To: linux-bluetooth; +Cc: padovan We need to use the _sync() version for cancelling the info and security timer in the L2CAP connection delete path. Otherwise the delayed work handler might run after the connection object is freed. Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> --- net/bluetooth/l2cap_core.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ae7fb27..09cd860 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1016,10 +1016,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) hci_chan_del(conn->hchan); if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) - __cancel_delayed_work(&conn->info_timer); + cancel_delayed_work_sync(&conn->info_timer); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { - __cancel_delayed_work(&conn->security_timer); + cancel_delayed_work_sync(&conn->security_timer); smp_chan_destroy(conn); } -- 1.7.8.rc4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path 2012-01-30 20:26 ` [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path Ulisses Furquim @ 2012-01-30 21:30 ` Marcel Holtmann 0 siblings, 0 replies; 9+ messages in thread From: Marcel Holtmann @ 2012-01-30 21:30 UTC (permalink / raw) To: Ulisses Furquim; +Cc: linux-bluetooth, padovan Hi Ulisses, > We need to use the _sync() version for cancelling the info and security > timer in the L2CAP connection delete path. Otherwise the delayed work > handler might run after the connection object is freed. > > Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> > --- > net/bluetooth/l2cap_core.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) Acked-by: Marcel Holtmann <marcel@holtmann.org> Regards Marcel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-01-30 20:26 [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim 2012-01-30 20:26 ` [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path Ulisses Furquim @ 2012-01-30 21:29 ` Marcel Holtmann 2012-01-30 21:42 ` Ulisses Furquim 2012-01-30 22:27 ` Johan Hedberg 2012-03-01 9:10 ` Andrei Emeltchenko 3 siblings, 1 reply; 9+ messages in thread From: Marcel Holtmann @ 2012-01-30 21:29 UTC (permalink / raw) To: Ulisses Furquim; +Cc: linux-bluetooth, padovan Hi Ulisses, > __cancel_delayed_work() is being used in some paths where we cannot > sleep waiting for the delayed work to finish. However, that function > might return while the timer is running and the work will be queued > again. Replace the calls with safer cancel_delayed_work() version > which spins until the timer handler finishes on other CPUs and > cancels the delayed work. > > Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> > --- I have the feeling that I already looked at this patch before. And given that it is v4, that might be true actually ;) Use the space between --- and diffstat to have some small changelog so I know what was different to the previous version. > include/net/bluetooth/l2cap.h | 4 ++-- > net/bluetooth/l2cap_core.c | 6 +++--- > 2 files changed, 5 insertions(+), 5 deletions(-) Acked-by: Marcel Holtmann <marcel@holtmann.org> Regards Marcel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-01-30 21:29 ` [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Marcel Holtmann @ 2012-01-30 21:42 ` Ulisses Furquim 0 siblings, 0 replies; 9+ messages in thread From: Ulisses Furquim @ 2012-01-30 21:42 UTC (permalink / raw) To: Marcel Holtmann; +Cc: linux-bluetooth, padovan Hi Marcel, On Mon, Jan 30, 2012 at 7:29 PM, Marcel Holtmann <marcel@holtmann.org> wrot= e: > Hi Ulisses, > >> __cancel_delayed_work() is being used in some paths where we cannot >> sleep waiting for the delayed work to finish. However, that function >> might return while the timer is running and the work will be queued >> again. Replace the calls with safer cancel_delayed_work() version >> which spins until the timer handler finishes on other CPUs and >> cancels the delayed work. >> >> Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> >> --- > > I have the feeling that I already looked at this patch before. And given > that it is v4, that might be true actually ;) > > Use the space between --- and diffstat to have some small changelog so I > know what was different to the previous version. Yes, you already seen this but I removed part of the patch to fix another problem. Sorry, forgot to include a message so you could know what has changed. >> =A0include/net/bluetooth/l2cap.h | =A0 =A04 ++-- >> =A0net/bluetooth/l2cap_core.c =A0 =A0| =A0 =A06 +++--- >> =A02 files changed, 5 insertions(+), 5 deletions(-) > > Acked-by: Marcel Holtmann <marcel@holtmann.org> > > Regards > > Marcel Regards, --=20 Ulisses Furquim ProFUSION embedded systems http://profusion.mobi Mobile: +55 19 9250 0942 Skype: ulissesffs ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-01-30 20:26 [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim 2012-01-30 20:26 ` [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path Ulisses Furquim 2012-01-30 21:29 ` [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Marcel Holtmann @ 2012-01-30 22:27 ` Johan Hedberg 2012-03-01 9:10 ` Andrei Emeltchenko 3 siblings, 0 replies; 9+ messages in thread From: Johan Hedberg @ 2012-01-30 22:27 UTC (permalink / raw) To: Ulisses Furquim; +Cc: linux-bluetooth, padovan Hi Ulisses, On Mon, Jan 30, 2012, Ulisses Furquim wrote: > __cancel_delayed_work() is being used in some paths where we cannot > sleep waiting for the delayed work to finish. However, that function > might return while the timer is running and the work will be queued > again. Replace the calls with safer cancel_delayed_work() version > which spins until the timer handler finishes on other CPUs and > cancels the delayed work. > > Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> > --- > include/net/bluetooth/l2cap.h | 4 ++-- > net/bluetooth/l2cap_core.c | 6 +++--- > 2 files changed, 5 insertions(+), 5 deletions(-) Both patches have bee applied to my bluetooth-next tree. Thanks. Johan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-01-30 20:26 [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim ` (2 preceding siblings ...) 2012-01-30 22:27 ` Johan Hedberg @ 2012-03-01 9:10 ` Andrei Emeltchenko 2012-03-01 12:23 ` Andrei Emeltchenko 2012-03-01 13:34 ` Ulisses Furquim 3 siblings, 2 replies; 9+ messages in thread From: Andrei Emeltchenko @ 2012-03-01 9:10 UTC (permalink / raw) To: Ulisses Furquim; +Cc: linux-bluetooth, padovan Hi All, On Mon, Jan 30, 2012 at 06:26:28PM -0200, Ulisses Furquim wrote: > __cancel_delayed_work() is being used in some paths where we cannot > sleep waiting for the delayed work to finish. However, that function > might return while the timer is running and the work will be queued > again. Replace the calls with safer cancel_delayed_work() version > which spins until the timer handler finishes on other CPUs and > cancels the delayed work. > > Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> > --- > include/net/bluetooth/l2cap.h | 4 ++-- > net/bluetooth/l2cap_core.c | 6 +++--- > 2 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h > index e7a8cc7..42fdbb8 100644 > --- a/include/net/bluetooth/l2cap.h > +++ b/include/net/bluetooth/l2cap.h > @@ -614,7 +614,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan, > { > BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); > > - if (!__cancel_delayed_work(work)) > + if (!cancel_delayed_work(work)) > l2cap_chan_hold(chan); > schedule_delayed_work(work, timeout); > } > @@ -624,7 +624,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, > { > bool ret; > > - ret = __cancel_delayed_work(work); > + ret = cancel_delayed_work(work); > if (ret) > l2cap_chan_put(chan); > I have some questions about delayed_work usage: When setting timer with l2cap_set_timer() we hold_chan if work may be running. So if previous work is cancelled OK we do not hold chan. Didn't we miss hold_chan here? Then in l2cap_clear_chan we put_chan if work cancelled OK, otherwise put_chan is done in delayed_work so we always put_chan. I am actually seeing some crashes in rare cases related to delayed work. Best regards Andrei Emeltchenko ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-03-01 9:10 ` Andrei Emeltchenko @ 2012-03-01 12:23 ` Andrei Emeltchenko 2012-03-01 13:34 ` Ulisses Furquim 1 sibling, 0 replies; 9+ messages in thread From: Andrei Emeltchenko @ 2012-03-01 12:23 UTC (permalink / raw) To: Ulisses Furquim, linux-bluetooth, padovan Hi, > > __cancel_delayed_work() is being used in some paths where we cannot > > sleep waiting for the delayed work to finish. However, that function > > might return while the timer is running and the work will be queued > > again. Replace the calls with safer cancel_delayed_work() version > > which spins until the timer handler finishes on other CPUs and > > cancels the delayed work. > > > > Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> > > --- > > include/net/bluetooth/l2cap.h | 4 ++-- > > net/bluetooth/l2cap_core.c | 6 +++--- > > 2 files changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h > > index e7a8cc7..42fdbb8 100644 > > --- a/include/net/bluetooth/l2cap.h > > +++ b/include/net/bluetooth/l2cap.h > > @@ -614,7 +614,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan, > > { > > BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); > > > > - if (!__cancel_delayed_work(work)) > > + if (!cancel_delayed_work(work)) > > l2cap_chan_hold(chan); > > schedule_delayed_work(work, timeout); > > } > > @@ -624,7 +624,7 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, > > { > > bool ret; > > > > - ret = __cancel_delayed_work(work); > > + ret = cancel_delayed_work(work); > > if (ret) > > l2cap_chan_put(chan); > > > > > I have some questions about delayed_work usage: > > When setting timer with l2cap_set_timer() we hold_chan if work may be > running. So if previous work is cancelled OK we do not hold chan. > > Didn't we miss hold_chan here? > > Then in l2cap_clear_chan we put_chan if work cancelled OK, otherwise > put_chan is done in delayed_work so we always put_chan. What about following change: diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index a357336..d61e158 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -628,17 +628,6 @@ static inline void l2cap_chan_unlock(struct l2cap_chan *chan) mutex_unlock(&chan->lock); } -static inline void l2cap_set_timer(struct l2cap_chan *chan, - struct delayed_work *work, long timeout) -{ - BT_DBG("chan %p state %s timeout %ld", chan, - state_to_string(chan->state), timeout); - - if (!cancel_delayed_work(work)) - l2cap_chan_hold(chan); - schedule_delayed_work(work, timeout); -} - static inline bool l2cap_clear_timer(struct l2cap_chan *chan, struct delayed_work *work) { @@ -651,6 +640,18 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, return ret; } +static inline void l2cap_set_timer(struct l2cap_chan *chan, + struct delayed_work *work, long timeout) +{ + BT_DBG("chan %p state %s timeout %ld", chan, + state_to_string(chan->state), timeout); + + l2cap_clear_timer(chan, work); + + l2cap_chan_hold(chan); + schedule_delayed_work(work, timeout); +} + #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ Best regards Andrei Emeltchenko ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() 2012-03-01 9:10 ` Andrei Emeltchenko 2012-03-01 12:23 ` Andrei Emeltchenko @ 2012-03-01 13:34 ` Ulisses Furquim 1 sibling, 0 replies; 9+ messages in thread From: Ulisses Furquim @ 2012-03-01 13:34 UTC (permalink / raw) To: Andrei Emeltchenko, Ulisses Furquim, linux-bluetooth, padovan Hi Andrei, On Thu, Mar 1, 2012 at 6:10 AM, Andrei Emeltchenko <andrei.emeltchenko.news@gmail.com> wrote: > Hi All, > > On Mon, Jan 30, 2012 at 06:26:28PM -0200, Ulisses Furquim wrote: >> __cancel_delayed_work() is being used in some paths where we cannot >> sleep waiting for the delayed work to finish. However, that function >> might return while the timer is running and the work will be queued >> again. Replace the calls with safer cancel_delayed_work() version >> which spins until the timer handler finishes on other CPUs and >> cancels the delayed work. >> >> Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi> Well, these comments are not really related to this specific patch. This change was just a replace of functions to cancel delayed work. > I have some questions about delayed_work usage: > > When setting timer with l2cap_set_timer() we hold_chan if work may be > running. So if previous work is cancelled OK we do not hold chan. > > Didn't we miss hold_chan here? > > Then in l2cap_clear_chan we put_chan if work cancelled OK, otherwise > put_chan is done in delayed_work so we always put_chan. > > I am actually seeing some crashes in rare cases related to delayed work. Do you have a log or something? Have you added the debug info to check hold/put usage? It'd be good to really understand the problem and fix it. It might be we're trying to be overly smart here and left some races. This code is very similar (if not equal) to the one we had before with timers. Regards, -- Ulisses Furquim ProFUSION embedded systems http://profusion.mobi Mobile: +55 19 9250 0942 Skype: ulissesffs ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-03-01 13:34 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-01-30 20:26 [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Ulisses Furquim 2012-01-30 20:26 ` [PATCH v4 2/2] Bluetooth: Fix possible use after free in delete path Ulisses Furquim 2012-01-30 21:30 ` Marcel Holtmann 2012-01-30 21:29 ` [PATCH v4 1/2] Bluetooth: Remove usage of __cancel_delayed_work() Marcel Holtmann 2012-01-30 21:42 ` Ulisses Furquim 2012-01-30 22:27 ` Johan Hedberg 2012-03-01 9:10 ` Andrei Emeltchenko 2012-03-01 12:23 ` Andrei Emeltchenko 2012-03-01 13:34 ` Ulisses Furquim
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).