From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 1/3] avrcp: Fix out-of-bounds parsing of ListPlayerAttributes response
Date: Fri, 28 Aug 2026 12:17:00 -0400 [thread overview]
Message-ID: <20260828161702.519421-1-luiz.dentz@gmail.com> (raw)
From: Bastien Nocera <hadess@hadess.net>
In profiles/audio/avrcp.c, avrcp_list_player_attributes_rsp() parsed the
response using hand-computed offsets into the operands buffer, without
accounting for the fact that operand_count spans the 7 byte AVRCP header
as well as the parameters:
- attrs is a 4 byte array which could be written out-of-bounds if a
length greater than 4 was declared in the first parameter byte.
- The attribute bytes were read with a bound derived from operand_count,
so a truncated response could be read past its end. As the receive
buffer is reused across packets, those stale bytes could be echoed
back to the peer in the following GetCurrentPlayerValue request.
- params_len was compared against count, which was only ever 0 at that
point, so the length of the PDU was in practice never validated.
Parse the response through a struct iovec using the util_iov_pull_*
helpers instead, so that the header and each subsequent field are bounds
checked as they are consumed and the remaining length is tracked for us.
This lets params_len be validated against the actual number of parameter
bytes received. The attribute count is still clamped to
AVRCP_ATTRIBUTE_LAST, which is what bounds the write into attrs.
Reported-by: @ax-nnlabs
Closes: https://github.com/bluez/bluez/security/advisories/GHSA-m2vx-pw5f-rc8v
---
profiles/audio/avrcp.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 3271b84782e8..906f93424872 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -2395,31 +2395,49 @@ static gboolean avrcp_list_player_attributes_rsp(struct avctp *conn,
uint8_t transaction, uint8_t *operands,
size_t operand_count, void *user_data)
{
+ struct iovec iov = { operands, operand_count };
uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
struct avrcp *session = user_data;
- struct avrcp_header *pdu = (void *) operands;
+ struct avrcp_header *pdu;
uint8_t len, count = 0;
int i;
if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED)
return FALSE;
- len = pdu->params[0];
+ pdu = util_iov_pull_mem(&iov, sizeof(*pdu));
+ if (!pdu) {
+ error("Invalid AVRCP header");
+ return FALSE;
+ }
- if (be16_to_cpu(pdu->params_len) < count) {
+ if (be16_to_cpu(pdu->params_len) != iov.iov_len) {
error("Invalid parameters");
return FALSE;
}
- for (i = 0; len > 0; len--, i++) {
+ if (!util_iov_pull_u8(&iov, &len))
+ return FALSE;
+
+ len = MIN(len, AVRCP_ATTRIBUTE_LAST);
+
+ for (i = 0; i < len; i++) {
+ uint8_t attr;
+
+ if (!util_iov_pull_u8(&iov, &attr))
+ break;
+
/* Don't query invalid attributes */
- if (pdu->params[i + 1] == AVRCP_ATTRIBUTE_ILLEGAL ||
- pdu->params[i + 1] > AVRCP_ATTRIBUTE_LAST)
+ if (attr == AVRCP_ATTRIBUTE_ILLEGAL ||
+ attr > AVRCP_ATTRIBUTE_LAST)
continue;
- attrs[count++] = pdu->params[i + 1];
+ attrs[count++] = attr;
}
+ if (!count)
+ return FALSE;
+
avrcp_get_current_player_value(session, attrs, count);
return FALSE;
--
2.54.0
next reply other threads:[~2026-08-28 16:17 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 16:17 Luiz Augusto von Dentz [this message]
2026-08-28 16:17 ` [PATCH BlueZ v1 2/3] avrcp: Fix out-of-bounds read parsing attribute lists Luiz Augusto von Dentz
2026-08-28 16:17 ` [PATCH BlueZ v1 3/3] avrcp: Use util_iov helpers to parse responses Luiz Augusto von Dentz
2026-08-28 22:20 ` [BlueZ,v1,1/3] avrcp: Fix out-of-bounds parsing of ListPlayerAttributes response bluez.test.bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260828161702.519421-1-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox