aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMaksim Yevmenkin <emax@FreeBSD.org>2005-08-31 18:13:23 +0000
committerMaksim Yevmenkin <emax@FreeBSD.org>2005-08-31 18:13:23 +0000
commit82e1becc5fe5b223116f2f75a8f16a7756faae30 (patch)
tree723ee550e984161491555f7f607278306e152baf /sys
parent7b7b9810bd0c9598201d349d4bb278eb5fe857f1 (diff)
downloadsrc-82e1becc5fe5b223116f2f75a8f16a7756faae30.tar.gz
src-82e1becc5fe5b223116f2f75a8f16a7756faae30.zip
Fix dangling callout problem in the Bluetooth L2CAP code that leads to
panic. The panic happens when outgoing L2CAP connection descriptor is deleted with the L2CAP command(s) pending in the queue. In this case when the last L2CAP command is deleted (due to cleanup) and reference counter for the L2CAP connection goes down to zero the auto disconnect timeout is incorrectly set. pjd gets credit for tracking this down and committing bandaid. Reported by: Jonatan B <onatan at gmail dot com> MFC after: 3 days
Notes
Notes: svn path=/head/; revision=149679
Diffstat (limited to 'sys')
-rw-r--r--sys/netgraph/bluetooth/include/ng_l2cap.h1
-rw-r--r--sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c3
-rw-r--r--sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c15
3 files changed, 14 insertions, 5 deletions
diff --git a/sys/netgraph/bluetooth/include/ng_l2cap.h b/sys/netgraph/bluetooth/include/ng_l2cap.h
index 094aad38b56d..f57b5cbe3d20 100644
--- a/sys/netgraph/bluetooth/include/ng_l2cap.h
+++ b/sys/netgraph/bluetooth/include/ng_l2cap.h
@@ -623,6 +623,7 @@ typedef struct {
#define NG_L2CAP_CON_OUTGOING (1 << 2) /* outgoing connection */
#define NG_L2CAP_CON_LP_TIMO (1 << 3) /* LP timeout */
#define NG_L2CAP_CON_AUTO_DISCON_TIMO (1 << 4) /* auto discon. timeout */
+#define NG_L2CAP_CON_DYING (1 << 5) /* connection is dying */
typedef struct {
u_int8_t state; /* connection state */
diff --git a/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c b/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c
index 06c19f613a8f..2e0efe392ef8 100644
--- a/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c
+++ b/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c
@@ -226,6 +226,9 @@ ng_l2cap_con_fail(ng_l2cap_con_p con, u_int16_t result)
"%s: %s - ACL connection failed, result=%d\n",
__func__, NG_NODE_NAME(l2cap->node), result);
+ /* Connection is dying */
+ con->flags |= NG_L2CAP_CON_DYING;
+
/* Clean command queue */
while (!TAILQ_EMPTY(&con->cmd_list)) {
cmd = TAILQ_FIRST(&con->cmd_list);
diff --git a/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c b/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
index 10eb89eea5d1..635298a4e3d3 100644
--- a/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
+++ b/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c
@@ -182,12 +182,14 @@ ng_l2cap_con_unref(ng_l2cap_con_p con)
* 2) connection is in OPEN state
* 3) it is an outgoing connection
* 4) disconnect timeout > 0
+ * 5) connection is not dying
*/
if ((con->refcnt == 0) &&
(con->state == NG_L2CAP_CON_OPEN) &&
(con->flags & NG_L2CAP_CON_OUTGOING) &&
- (con->l2cap->discon_timo > 0))
+ (con->l2cap->discon_timo > 0) &&
+ ((con->flags & NG_L2CAP_CON_DYING) == 0))
ng_l2cap_discon_timeout(con);
} /* ng_l2cap_con_unref */
@@ -273,11 +275,14 @@ ng_l2cap_free_con(ng_l2cap_con_p con)
ng_l2cap_free_cmd(cmd);
}
+ if (con->flags & (NG_L2CAP_CON_AUTO_DISCON_TIMO|NG_L2CAP_CON_LP_TIMO))
+ panic(
+"%s: %s - timeout pending! state=%d, flags=%#x\n",
+ __func__, NG_NODE_NAME(con->l2cap->node),
+ con->state, con->flags);
+
LIST_REMOVE(con, next);
- if (con->flags & NG_L2CAP_CON_AUTO_DISCON_TIMO)
- ng_l2cap_discon_untimeout(con);
- if (con->flags & NG_L2CAP_CON_LP_TIMO)
- ng_l2cap_lp_untimeout(con);
+
bzero(con, sizeof(*con));
FREE(con, M_NETGRAPH_L2CAP);
} /* ng_l2cap_free_con */