Skip to content

Commit f5f9872

Browse files
lylezhu2012henrikbrixandersen
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]> (cherry picked from commit 37d62c6)
1 parent 2c2540e commit f5f9872

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

subsys/bluetooth/host/rfcomm.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,10 +1454,13 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
14541454
{
14551455
struct bt_rfcomm_session *session = RFCOMM_SESSION(chan);
14561456
struct bt_rfcomm_hdr *hdr = (void *)buf->data;
1457+
struct bt_rfcomm_hdr_ext *hdr_ext = (void *)buf->data;
14571458
uint8_t dlci, frame_type, fcs, fcs_len;
1459+
uint16_t msg_len;
1460+
uint16_t hdr_len;
14581461

14591462
/* Need to consider FCS also*/
1460-
if (buf->len < (sizeof(*hdr) + 1)) {
1463+
if (buf->len < (sizeof(*hdr) + sizeof(fcs))) {
14611464
LOG_ERR("Too small RFCOMM Frame");
14621465
return 0;
14631466
}
@@ -1467,19 +1470,28 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
14671470

14681471
LOG_DBG("session %p dlci %x type %x", session, dlci, frame_type);
14691472

1470-
fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH :
1471-
BT_RFCOMM_FCS_LEN_NON_UIH;
1472-
fcs = *(net_buf_tail(buf) - 1);
1473+
if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) {
1474+
msg_len = BT_RFCOMM_GET_LEN_EXTENDED(hdr_ext->hdr.length, hdr_ext->second_length);
1475+
hdr_len = sizeof(*hdr_ext);
1476+
} else {
1477+
msg_len = BT_RFCOMM_GET_LEN(hdr->length);
1478+
hdr_len = sizeof(*hdr);
1479+
}
1480+
1481+
if (buf->len < (hdr_len + msg_len + sizeof(fcs))) {
1482+
LOG_ERR("Too small RFCOMM information (%d < %d)", buf->len,
1483+
hdr_len + msg_len + sizeof(fcs));
1484+
return 0;
1485+
}
1486+
1487+
fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH : hdr_len;
1488+
fcs = *(net_buf_tail(buf) - sizeof(fcs));
14731489
if (!rfcomm_check_fcs(fcs_len, buf->data, fcs)) {
14741490
LOG_ERR("FCS check failed");
14751491
return 0;
14761492
}
14771493

1478-
if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) {
1479-
net_buf_pull(buf, sizeof(*hdr) + 1);
1480-
} else {
1481-
net_buf_pull(buf, sizeof(*hdr));
1482-
}
1494+
net_buf_pull(buf, hdr_len);
14831495

14841496
switch (frame_type) {
14851497
case BT_RFCOMM_SABM:
@@ -1489,8 +1501,7 @@ static int rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
14891501
if (!dlci) {
14901502
rfcomm_handle_msg(session, buf);
14911503
} else {
1492-
rfcomm_handle_data(session, buf, dlci,
1493-
BT_RFCOMM_GET_PF(hdr->control));
1504+
rfcomm_handle_data(session, buf, dlci, BT_RFCOMM_GET_PF(hdr->control));
14941505
}
14951506
break;
14961507
case BT_RFCOMM_DISC:

subsys/bluetooth/host/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)