summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_core.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-02-16 11:42:11 +0200
committerMarcel Holtmann <marcel@holtmann.org>2015-02-16 16:49:36 +0100
commit315917e0a6d552a33f774935d8897ec1697605dd (patch)
treec1c3f68702d9e13d72dfe0ad061f49631399a044 /net/bluetooth/l2cap_core.c
parent035a07d5df7003bc6954f0aa42174416b775021c (diff)
downloadlinux-stable-315917e0a6d552a33f774935d8897ec1697605dd.tar.gz
linux-stable-315917e0a6d552a33f774935d8897ec1697605dd.tar.bz2
linux-stable-315917e0a6d552a33f774935d8897ec1697605dd.zip
Bluetooth: Fix accepting early data on fixed channels
On BR/EDR the L2CAP channel instances for fixed channels have so far been marked as ready only once the L2CAP information req/rsp procedure is complete and we have the fixed channel mask. This could however lead to data being dropped if we receive it on the channel before knowing the remote mask. Since it is valid for a remote to send data this early, simply assume that the channel is supported when we receive data on it. So far this hasn't been noticed much because of limited use of fixed channels on BR/EDR, but e.g. with SMP over BR/EDR this is already now visible with automated tests failing randomly. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r--net/bluetooth/l2cap_core.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 6ba33f9631e8..ec6f78e481dc 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1244,6 +1244,13 @@ static void l2cap_move_done(struct l2cap_chan *chan)
static void l2cap_chan_ready(struct l2cap_chan *chan)
{
+ /* The channel may have already been flagged as connected in
+ * case of receiving data before the L2CAP info req/rsp
+ * procedure is complete.
+ */
+ if (chan->state == BT_CONNECTED)
+ return;
+
/* This clears all conf flags, including CONF_NOT_COMPLETE */
chan->conf_state = 0;
__clear_chan_timer(chan);
@@ -6785,6 +6792,13 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
BT_DBG("chan %p, len %d", chan, skb->len);
+ /* If we receive data on a fixed channel before the info req/rsp
+ * procdure is done simply assume that the channel is supported
+ * and mark it as ready.
+ */
+ if (chan->chan_type == L2CAP_CHAN_FIXED)
+ l2cap_chan_ready(chan);
+
if (chan->state != BT_CONNECTED)
goto drop;