Skip to content

Commit

Permalink
Bluetooth: AVDTP: Check buffer length before pulling it
Browse files Browse the repository at this point in the history
Check the remaining data length of net buffer before pulling data from
it.

Fixes zephyrproject-rtos#83024

Signed-off-by: Lyle Zhu <[email protected]>
  • Loading branch information
lylezhu2012 committed Dec 16, 2024
1 parent c616a17 commit 846936f
Showing 1 changed file with 81 additions and 3 deletions.
84 changes: 81 additions & 3 deletions subsys/bluetooth/host/classic/avdtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ static void avdtp_discover_handler(struct bt_avdtp *session,
DISCOVER_REQ(session->req)->status = 0;
DISCOVER_REQ(session->req)->buf = buf;
} else if (msg_type == BT_AVDTP_REJECT) {
if (buf->len < 1) {
LOG_WRN("Invalid RSP frame");
return;
}

DISCOVER_REQ(session->req)->status = net_buf_pull_u8(buf);
} else if (msg_type == BT_AVDTP_GEN_REJECT) {
DISCOVER_REQ(session->req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
Expand Down Expand Up @@ -266,6 +271,11 @@ static void avdtp_get_capabilities_handler(struct bt_avdtp *session,
struct bt_avdtp_sep *sep;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->get_capabilities_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -320,6 +330,11 @@ static void avdtp_get_capabilities_handler(struct bt_avdtp *session,
GET_CAP_REQ(session->req)->buf = buf;
}
} else if (msg_type == BT_AVDTP_REJECT) {
if (buf->len < 1) {
LOG_WRN("Invalid RSP frame");
return;
}

GET_CAP_REQ(session->req)->status = net_buf_pull_u8(buf);
} else if (msg_type == BT_AVDTP_GEN_REJECT) {
GET_CAP_REQ(session->req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
Expand All @@ -342,6 +357,11 @@ static void avdtp_process_configuration(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->set_configuration_ind == NULL)) {
err = -ENOTSUP;
Expand All @@ -352,6 +372,11 @@ static void avdtp_process_configuration(struct bt_avdtp *session,
} else {
uint8_t int_seid;

if (buf->len < 1) {
LOG_WRN("Invalid INT SEID");
return;
}

/* INT Stream Endpoint ID */
int_seid = net_buf_pull_u8(buf);
err = session->ops->set_configuration_ind(session,
Expand Down Expand Up @@ -399,6 +424,11 @@ static void avdtp_process_configuration(struct bt_avdtp *session,
SET_CONF_REQ(req)->status = 0;
SET_CONF_REQ(req)->sep->state = AVDTP_CONFIGURED;
} else if (msg_type == BT_AVDTP_REJECT) {
if (buf->len < 2) {
LOG_WRN("Invalid RSP frame");
return;
}

/* Service Category */
net_buf_pull_u8(buf);
SET_CONF_REQ(req)->status = net_buf_pull_u8(buf);
Expand Down Expand Up @@ -458,6 +488,11 @@ static void avdtp_open_handler(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->open_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -510,6 +545,11 @@ static void avdtp_open_handler(struct bt_avdtp *session,
return;
}
} else if (msg_type == BT_AVDTP_REJECT) {
if (buf->len < 1) {
LOG_WRN("Invalid RSP frame");
return;
}

OPEN_REQ(req)->status = net_buf_pull_u8(buf);
} else if (msg_type == BT_AVDTP_GEN_REJECT) {
OPEN_REQ(req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
Expand All @@ -535,6 +575,11 @@ static void avdtp_start_handler(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->start_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -584,6 +629,11 @@ static void avdtp_start_handler(struct bt_avdtp *session,
} else if (msg_type == BT_AVDTP_REJECT) {
uint8_t acp_seid;

if (buf->len < 2) {
LOG_WRN("Invalid RSP frame");
return;
}

acp_seid = net_buf_pull_u8(buf);
if (acp_seid != START_REQ(req)->acp_stream_ep_id) {
return;
Expand Down Expand Up @@ -611,6 +661,11 @@ static void avdtp_close_handler(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->close_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -660,6 +715,11 @@ static void avdtp_suspend_handler(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->suspend_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -708,6 +768,11 @@ static void avdtp_abort_handler(struct bt_avdtp *session,
struct net_buf *rsp_buf;
uint8_t error_code = 0;

if (buf->len < 1) {
LOG_WRN("Invalid ACP SEID");
return;
}

sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
if ((sep == NULL) || (session->ops->abort_ind == NULL)) {
err = -ENOTSUP;
Expand Down Expand Up @@ -1201,19 +1266,32 @@ int bt_avdtp_parse_capability_codec(struct net_buf *buf,
case BT_AVDTP_SERVICE_HEADER_COMPRESSION:
case BT_AVDTP_SERVICE_MULTIPLEXING:
case BT_AVDTP_SERVICE_DELAY_REPORTING:
if (buf->len < 1) {
return -EINVAL;
}

length = net_buf_pull_u8(buf);
if (buf->len < length) {
return -EINVAL;
}

if (length > 0) {
net_buf_pull_mem(buf, length);
}
break;

case BT_AVDTP_SERVICE_MEDIA_CODEC:
if (buf->len < 1) {
return -EINVAL;
}

length = net_buf_pull_u8(buf);
if (buf->len < length) {
return -EINVAL;
}

if (length > 3) {
data = net_buf_pull_u8(buf);
if (net_buf_tailroom(buf) < (length - 1)) {
return -EINVAL;
}
if (data == BT_AVDTP_AUDIO) {
data = net_buf_pull_u8(buf);
*codec_type = data;
Expand Down

0 comments on commit 846936f

Please sign in to comment.