Skip to content

Commit 37d62c6

Browse files
lylezhu2012aescolar
authored andcommitted
Bluetooth: RFCOMM: check the validity of received frame
Check whether the received frame is complete by comparing the length of the received data with the frame data. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 28eb135 commit 37d62c6

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

subsys/bluetooth/host/classic/rfcomm.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,10 +1494,13 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
14941494
{
14951495
struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);
14961496
struct bt_rfcomm_hdr *hdr = (void *)buf->data;
1497+
struct bt_rfcomm_hdr_ext *hdr_ext = (void *)buf->data;
14971498
uint8_t dlci, frame_type, fcs, fcs_len;
1499+
uint16_t msg_len;
1500+
uint16_t hdr_len;
14981501

14991502
/* Need to consider FCS also*/
1500-
if (buf->len < (sizeof(*hdr) + 1)) {
1503+
if (buf->len < (sizeof(*hdr) + sizeof(fcs))) {
15011504
LOG_ERR("Too small RFCOMM Frame");
15021505
return 0;
15031506
}
@@ -1507,19 +1510,28 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
15071510

15081511
LOG_DBG("session %p dlci %x type %x", session, dlci, frame_type);
15091512

1510-
fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH :
1511-
BT_RFCOMM_FCS_LEN_NON_UIH;
1512-
fcs = *(net_buf_tail(buf) - 1);
1513+
if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) {
1514+
msg_len = BT_RFCOMM_GET_LEN_EXTENDED(hdr_ext->hdr.length, hdr_ext->second_length);
1515+
hdr_len = sizeof(*hdr_ext);
1516+
} else {
1517+
msg_len = BT_RFCOMM_GET_LEN(hdr->length);
1518+
hdr_len = sizeof(*hdr);
1519+
}
1520+
1521+
if (buf->len < (hdr_len + msg_len + sizeof(fcs))) {
1522+
LOG_ERR("Too small RFCOMM information (%d < %d)", buf->len,
1523+
hdr_len + msg_len + sizeof(fcs));
1524+
return 0;
1525+
}
1526+
1527+
fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH : hdr_len;
1528+
fcs = *(net_buf_tail(buf) - sizeof(fcs));
15131529
if (!rfcomm_check_fcs(fcs_len, buf->data, fcs)) {
15141530
LOG_ERR("FCS check failed");
15151531
return 0;
15161532
}
15171533

1518-
if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) {
1519-
net_buf_pull(buf, sizeof(*hdr) + 1);
1520-
} else {
1521-
net_buf_pull(buf, sizeof(*hdr));
1522-
}
1534+
net_buf_pull(buf, hdr_len);
15231535

15241536
switch (frame_type) {
15251537
case BT_RFCOMM_SABM:
@@ -1529,8 +1541,7 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
15291541
if (!dlci) {
15301542
rfcomm_handle_msg(session, buf);
15311543
} else {
1532-
rfcomm_handle_data(session, buf, dlci,
1533-
BT_RFCOMM_GET_PF(hdr->control));
1544+
rfcomm_handle_data(session, buf, dlci, BT_RFCOMM_GET_PF(hdr->control));
15341545
}
15351546
break;
15361547
case BT_RFCOMM_DISC:

subsys/bluetooth/host/classic/rfcomm_internal.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ struct bt_rfcomm_hdr {
4949
uint8_t length;
5050
} __packed;
5151

52+
struct bt_rfcomm_hdr_ext {
53+
struct bt_rfcomm_hdr hdr;
54+
uint8_t second_length;
55+
} __packed;
56+
5257
#define BT_RFCOMM_SABM 0x2f
5358
#define BT_RFCOMM_UA 0x63
5459
#define BT_RFCOMM_UIH 0xef
@@ -137,13 +142,14 @@ struct bt_rfcomm_rpn {
137142
sizeof(struct bt_rfcomm_hdr) + 1 + (mtu) + \
138143
BT_RFCOMM_FCS_SIZE)
139144

140-
#define BT_RFCOMM_GET_DLCI(addr) (((addr) & 0xfc) >> 2)
141-
#define BT_RFCOMM_GET_FRAME_TYPE(ctrl) ((ctrl) & 0xef)
142-
#define BT_RFCOMM_GET_MSG_TYPE(type) (((type) & 0xfc) >> 2)
143-
#define BT_RFCOMM_GET_MSG_CR(type) (((type) & 0x02) >> 1)
144-
#define BT_RFCOMM_GET_LEN(len) (((len) & 0xfe) >> 1)
145-
#define BT_RFCOMM_GET_CHANNEL(dlci) ((dlci) >> 1)
146-
#define BT_RFCOMM_GET_PF(ctrl) (((ctrl) & 0x10) >> 4)
145+
#define BT_RFCOMM_GET_DLCI(addr) (((addr) & 0xfc) >> 2)
146+
#define BT_RFCOMM_GET_FRAME_TYPE(ctrl) ((ctrl) & 0xef)
147+
#define BT_RFCOMM_GET_MSG_TYPE(type) (((type) & 0xfc) >> 2)
148+
#define BT_RFCOMM_GET_MSG_CR(type) (((type) & 0x02) >> 1)
149+
#define BT_RFCOMM_GET_LEN(len) (((len) & 0xfe) >> 1)
150+
#define BT_RFCOMM_GET_LEN_EXTENDED(first, second) ((((first) & 0xfe) >> 1) | ((second) << 7))
151+
#define BT_RFCOMM_GET_CHANNEL(dlci) ((dlci) >> 1)
152+
#define BT_RFCOMM_GET_PF(ctrl) (((ctrl) & 0x10) >> 4)
147153

148154
#define BT_RFCOMM_SET_ADDR(dlci, cr) ((((dlci) & 0x3f) << 2) | \
149155
((cr) << 1) | 0x01)

0 commit comments

Comments
 (0)