Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: AVDTP: Check buffer length before pulling it #83026

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading