Skip to content

Commit 22c14df

Browse files
lylezhu2012henrikbrixandersen
authored andcommitted
Bluetooth: Classic: SDP: Check max attr byte count for req and rsp
In the SDP specification, the `MaximumAttributeByteCount` of SA and SSA should be in range 0x0007-0xffff. But in the current implementation, this value is not checked both SDP server and client sides. Check the `MaximumAttributeByteCount` when receiving the SA or SSA request on SDP server side. Check the tail room of the receiving buffer before sending the SA or SSA request on SDP client side. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 1192dbf commit 22c14df

File tree

1 file changed

+35
-2
lines changed
  • subsys/bluetooth/host/classic

1 file changed

+35
-2
lines changed

subsys/bluetooth/host/classic/sdp.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ NET_BUF_POOL_FIXED_DEFINE(sdp_pool, CONFIG_BT_MAX_CONN, BT_L2CAP_BUF_SIZE(SDP_MT
8383

8484
#define SDP_CLIENT_MTU 64
8585

86+
#define SDP_SA_MAX_ATTR_BYTE_COUNT 0xffff
87+
#define SDP_SA_MIN_ATTR_BYTE_COUNT 0x0007
88+
89+
#define SDP_SA_ATTR_BYTE_IN_RANGE(count) \
90+
((count) >= SDP_SA_MIN_ATTR_BYTE_COUNT && (count) <= SDP_SA_MAX_ATTR_BYTE_COUNT)
91+
92+
#define SDP_SSA_MAX_ATTR_BYTE_COUNT 0xffff
93+
#define SDP_SSA_MIN_ATTR_BYTE_COUNT 0x0007
94+
95+
#define SDP_SSA_ATTR_BYTE_IN_RANGE(count) \
96+
((count) >= SDP_SSA_MIN_ATTR_BYTE_COUNT && (count) <= SDP_SSA_MAX_ATTR_BYTE_COUNT)
97+
8698
enum sdp_client_state {
8799
SDP_CLIENT_RELEASED,
88100
SDP_CLIENT_CONNECTING,
@@ -1273,6 +1285,10 @@ static uint16_t sdp_svc_att_req(struct bt_sdp *sdp, struct net_buf *buf, uint16_
12731285

12741286
svc_rec_hdl = net_buf_pull_be32(buf);
12751287
max_att_len = net_buf_pull_be16(buf);
1288+
if (!SDP_SA_ATTR_BYTE_IN_RANGE(max_att_len)) {
1289+
LOG_WRN("Invalid max attribute length %u", max_att_len);
1290+
return BT_SDP_INVALID_SYNTAX;
1291+
}
12761292

12771293
/* Set up the filters */
12781294
res = get_att_search_list(buf, filter, ARRAY_SIZE(filter), &num_filters);
@@ -1404,6 +1420,11 @@ static uint16_t sdp_svc_search_att_req(struct bt_sdp *sdp, struct net_buf *buf,
14041420
}
14051421

14061422
max_att_len = net_buf_pull_be16(buf);
1423+
if (!SDP_SSA_ATTR_BYTE_IN_RANGE(max_att_len)) {
1424+
LOG_WRN("Invalid max attribute length %u", max_att_len);
1425+
return BT_SDP_INVALID_SYNTAX;
1426+
}
1427+
14071428
if (max_att_len < sizeof(*seq)) {
14081429
LOG_WRN("Invalid maximum attribute byte count %u < %u", max_att_len, sizeof(*seq));
14091430
return BT_SDP_INVALID_SYNTAX;
@@ -1860,13 +1881,19 @@ static int sdp_client_sa_search(struct bt_sdp_client *session,
18601881
/* Update context param directly. */
18611882
session->param = param;
18621883

1884+
len = net_buf_tailroom(session->rec_buf);
1885+
if (!SDP_SA_ATTR_BYTE_IN_RANGE(len)) {
1886+
LOG_WRN("No more space to start next SDP discovery");
1887+
return -ENOMEM;
1888+
}
1889+
18631890
buf = bt_sdp_create_pdu();
18641891

18651892
/* Add service record handle */
18661893
net_buf_add_be32(buf, param->handle);
18671894

18681895
/* Set attribute max bytes count to be returned from server */
1869-
net_buf_add_be16(buf, net_buf_tailroom(session->rec_buf));
1896+
net_buf_add_be16(buf, len);
18701897

18711898
/* Check the tailroom of the buffer */
18721899
len = sdp_client_get_total_len(session, param);
@@ -1908,6 +1935,12 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
19081935
/* Update context param directly. */
19091936
session->param = param;
19101937

1938+
len = net_buf_tailroom(session->rec_buf);
1939+
if (!SDP_SSA_ATTR_BYTE_IN_RANGE(len)) {
1940+
LOG_WRN("No more space to start next SDP discovery");
1941+
return -ENOMEM;
1942+
}
1943+
19111944
buf = bt_sdp_create_pdu();
19121945

19131946
/* BT_SDP_SEQ8 means length of sequence is on additional next byte */
@@ -1940,7 +1973,7 @@ static int sdp_client_ssa_search(struct bt_sdp_client *session,
19401973
}
19411974

19421975
/* Set attribute max bytes count to be returned from server */
1943-
net_buf_add_be16(buf, net_buf_tailroom(session->rec_buf));
1976+
net_buf_add_be16(buf, len);
19441977

19451978
/* Check the tailroom of the buffer */
19461979
len = sdp_client_get_total_len(session, param);

0 commit comments

Comments
 (0)