Skip to content

Commit 61a939c

Browse files
author
Johan Hedberg
committed
Bluetooth: Queue incoming ACL data until BT_CONNECTED state is reached
This patch adds a queue for incoming L2CAP data that's received before l2cap_connect_cfm is called and processes the data once l2cap_connect_cfm is called. This way we ensure that we have e.g. all remote features before processing L2CAP signaling data (which is very important for making the correct security decisions). The processing of the pending rx data needs to be done through queue_work since unlike l2cap_recv_acldata, l2cap_connect_cfm is called with the hci_dev lock held which could cause potential deadlocks. Signed-off-by: Johan Hedberg <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 162b49e commit 61a939c

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

include/net/bluetooth/l2cap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,9 @@ struct l2cap_conn {
624624
__u32 rx_len;
625625
__u8 tx_ident;
626626

627+
struct sk_buff_head pending_rx;
628+
struct work_struct pending_rx_work;
629+
627630
__u8 disc_reason;
628631

629632
struct delayed_work security_timer;

net/bluetooth/l2cap_core.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
15501550
}
15511551

15521552
mutex_unlock(&conn->chan_lock);
1553+
1554+
queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
15531555
}
15541556

15551557
/* Notify sockets that we cannot guaranty reliability anymore */
@@ -1675,6 +1677,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
16751677

16761678
kfree_skb(conn->rx_skb);
16771679

1680+
skb_queue_purge(&conn->pending_rx);
1681+
flush_work(&conn->pending_rx_work);
1682+
16781683
l2cap_unregister_all_users(conn);
16791684

16801685
mutex_lock(&conn->chan_lock);
@@ -6880,9 +6885,16 @@ static void l2cap_att_channel(struct l2cap_conn *conn,
68806885
static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
68816886
{
68826887
struct l2cap_hdr *lh = (void *) skb->data;
6888+
struct hci_conn *hcon = conn->hcon;
68836889
u16 cid, len;
68846890
__le16 psm;
68856891

6892+
if (hcon->state != BT_CONNECTED) {
6893+
BT_DBG("queueing pending rx skb");
6894+
skb_queue_tail(&conn->pending_rx, skb);
6895+
return;
6896+
}
6897+
68866898
skb_pull(skb, L2CAP_HDR_SIZE);
68876899
cid = __le16_to_cpu(lh->cid);
68886900
len = __le16_to_cpu(lh->len);
@@ -6928,6 +6940,18 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
69286940
}
69296941
}
69306942

6943+
static void process_pending_rx(struct work_struct *work)
6944+
{
6945+
struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
6946+
pending_rx_work);
6947+
struct sk_buff *skb;
6948+
6949+
BT_DBG("");
6950+
6951+
while ((skb = skb_dequeue(&conn->pending_rx)))
6952+
l2cap_recv_frame(conn, skb);
6953+
}
6954+
69316955
static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
69326956
{
69336957
struct l2cap_conn *conn = hcon->l2cap_data;
@@ -6983,6 +7007,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
69837007
else
69847008
INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
69857009

7010+
skb_queue_head_init(&conn->pending_rx);
7011+
INIT_WORK(&conn->pending_rx_work, process_pending_rx);
7012+
69867013
conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
69877014

69887015
return conn;

0 commit comments

Comments
 (0)