This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new c95c546c099 wireless/bluetooth: Fix record stride in descriptor 
discovery response.
c95c546c099 is described below

commit c95c546c0993a1494cfd7f24c6265e62bef51f7f
Author: Alan Carvalho de Assis <[email protected]>
AuthorDate: Thu Sep 17 10:12:35 2026 -0300

    wireless/bluetooth: Fix record stride in descriptor discovery response.
    
    att_find_info_rsp() computed the per-record stride with sizeof(info.i16)
    and sizeof(info.i128), but "info" is a union of two pointers, so both
    expressions evaluate to the pointer width instead of the size of the
    record that the response format selects.  The records are 4 octets for a
    16-bit UUID and 18 octets for a 128-bit UUID, so the 128-bit path
    advanced by 4 (or 8) octets per iteration while reading an 18-octet
    record: handles and UUIDs were parsed from the wrong offsets and the walk
    ran past the end of the received PDU.  On 64-bit builds the 16-bit path
    was wrong too.
    
    Take the stride from the record structures, and require the response to
    carry whole records before walking it, since the loop advances one record
    at a time and a partial trailing record would be parsed as a whole one.
    
    Ref: Core v6.0, Vol 3, Part F, 3.4.3.2 (ATT_FIND_INFORMATION_RSP)
    Testing: sim:bluetooth builds with Make, no new warnings.  Not yet
    exercised at runtime; the scriptable controller that can inject a
    malformed Find Information Response is added separately.
    
    Signed-off-by: Alan C. Assis <[email protected]>
    Assisted-by: Claude Code Opus 5
---
 wireless/bluetooth/bt_gatt.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/wireless/bluetooth/bt_gatt.c b/wireless/bluetooth/bt_gatt.c
index 4f49fc72c78..5977497b296 100644
--- a/wireless/bluetooth/bt_gatt.c
+++ b/wireless/bluetooth/bt_gatt.c
@@ -952,22 +952,36 @@ static void att_find_info_rsp(FAR struct bt_conn_s *conn, 
uint8_t err,
     {
       case BT_ATT_INFO_16:
         uuid.type = BT_UUID_16;
-        len = sizeof(info.i16);
+        len = sizeof(struct bt_att_info_16_s);
         break;
 
       case BT_ATT_INFO_128:
         uuid.type = BT_UUID_128;
-        len = sizeof(info.i128);
+        len = sizeof(struct bt_att_info_128_s);
         break;
 
       default:
-      wlerr("ERROR: Invalid format %u\n", rsp->format);
+        wlerr("ERROR: Invalid format %u\n", rsp->format);
+        goto done;
+    }
+
+  /* The response is the format octet followed by whole records of the
+   * size the format selects.  Anything else is malformed and must not be
+   * walked, since the loop below advances by one record at a time.
+   */
+
+  length--;
+
+  if (length < len || (length % len) != 0)
+    {
+      wlerr("ERROR: Invalid info length %u for format %u\n", length,
+            rsp->format);
       goto done;
     }
 
   /* Parse descriptors found */
 
-  for (length--, pdu = rsp->info; length >= len; length -= len, pdu += len)
+  for (pdu = rsp->info; length >= len; length -= len, pdu += len)
     {
       FAR const struct bt_gatt_attr_s *attr;
 

Reply via email to