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

commit 9bc9df20823c14738331b0ba46347a854ff37872
Author: raiden00pl <[email protected]>
AuthorDate: Thu Oct 22 14:47:38 2026 +0200

    wireless/ieee802154: free the frame of a data indication with it
    
    Command, beacon and ACK frames and an empty extracted data frame were
    freed without their IOB, so each one leaked an IOB. A data indication
    owns its frame: ieee802154_primitive_free() frees it, and a caller that
    keeps the frame clears the frame field first.
    
    Assisted-by: Claude Code
    Signed-off-by: raiden00pl <[email protected]>
---
 drivers/wireless/ieee802154/xbee/xbee.c            |  1 -
 include/nuttx/wireless/ieee802154/ieee802154_mac.h |  3 ++-
 wireless/ieee802154/ieee802154_primitive.c         | 10 ++++++++++
 wireless/ieee802154/mac802154.c                    |  1 -
 wireless/ieee802154/mac802154_device.c             |  6 +-----
 5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/wireless/ieee802154/xbee/xbee.c 
b/drivers/wireless/ieee802154/xbee/xbee.c
index 11d5fa0eba5..692feebf47f 100644
--- a/drivers/wireless/ieee802154/xbee/xbee.c
+++ b/drivers/wireless/ieee802154/xbee/xbee.c
@@ -1022,7 +1022,6 @@ static void xbee_notify_worker(FAR void *arg)
 
           if (dispose)
             {
-              iob_free(primitive->u.dataind.frame);
               ieee802154_primitive_free(primitive);
             }
         }
diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h 
b/include/nuttx/wireless/ieee802154/ieee802154_mac.h
index 98254572571..58641d58a3f 100644
--- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h
+++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h
@@ -1849,7 +1849,8 @@ FAR struct ieee802154_primitive_s 
*ieee802154_primitive_allocate(void);
  *   The ieee802154_primitive_free function will return a primitive
  *   structure to the free pool if it was a pre-allocated primitive
  *   structure. If the primitive was allocated dynamically it will be
- *   deallocated.
+ *   deallocated.  The frame IOB of a data indication is freed with it, a
+ *   caller that keeps the frame sets the frame field to NULL first.
  *
  * Input Parameters:
  *   prim - primitive structure to free
diff --git a/wireless/ieee802154/ieee802154_primitive.c 
b/wireless/ieee802154/ieee802154_primitive.c
index 01bae5f48c1..e6f9ecfac1e 100644
--- a/wireless/ieee802154/ieee802154_primitive.c
+++ b/wireless/ieee802154/ieee802154_primitive.c
@@ -33,6 +33,7 @@
 
 #include <nuttx/spinlock.h>
 #include <nuttx/kmalloc.h>
+#include <nuttx/mm/iob.h>
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
 
 #include "mac802154.h"
@@ -357,6 +358,15 @@ void ieee802154_primitive_free(FAR struct 
ieee802154_primitive_s *prim)
       return;
     }
 
+  /* A data indication owns its frame */
+
+  if (prim->type == IEEE802154_PRIMITIVE_IND_DATA &&
+      prim->u.dataind.frame != NULL)
+    {
+      iob_free(prim->u.dataind.frame);
+      prim->u.dataind.frame = NULL;
+    }
+
 #if CONFIG_IEEE802154_PRIMITIVE_PREALLOC > 0
   irqstate_t flags;
   FAR struct ieee802154_priv_primitive_s *priv =
diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c
index 901653c35cf..a8e2913f7d0 100644
--- a/wireless/ieee802154/mac802154.c
+++ b/wireless/ieee802154/mac802154.c
@@ -445,7 +445,6 @@ static void mac802154_notify_worker(FAR void *arg)
 
           if (dispose)
             {
-              iob_free(primitive->u.dataind.frame);
               ieee802154_primitive_free(primitive);
             }
         }
diff --git a/wireless/ieee802154/mac802154_device.c 
b/wireless/ieee802154/mac802154_device.c
index f53c27adafb..a8c26f132ac 100644
--- a/wireless/ieee802154/mac802154_device.c
+++ b/wireless/ieee802154/mac802154_device.c
@@ -456,11 +456,7 @@ static ssize_t mac802154dev_read(FAR struct file *filep, 
FAR char *buffer,
   rx->meta.flink = NULL;
   rx->meta.frame = NULL;
 
-  /* Free the IOB */
-
-  iob_free(ind->frame);
-
-  /* Deallocate the data indication */
+  /* Deallocate the data indication and its IOB */
 
   ieee802154_primitive_free((FAR struct ieee802154_primitive_s *)ind);
 

Reply via email to