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-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 642720e9b examples/configdata: exercise unregister/register lifetime
642720e9b is described below

commit 642720e9b4bfd885b0f11814812df120ef7edefd
Author: Arnav Sharma <[email protected]>
AuthorDate: Wed Sep 16 23:12:10 2026 +0530

    examples/configdata: exercise unregister/register lifetime
    
    Add a regression test for apache/nuttx#20166 to the configdata
    example, which runs automatically in every sim:configdata build.
    After the normal configdata test loops, close the long-lived
    descriptor and run a full lifetime cycle on /dev/config:
    
    - mtdconfig_unregister() must succeed,
    - the unregistered device must no longer be openable (ENOENT),
    - the same MTD device must be registerable again and usable,
    - a final unregister must succeed, leaving the device unregistered.
    
    Before the driver fix this crashes deterministically: the old
    mtdconfig_unregister_by_path() freed the private device structure
    before closing its temporary file, so the subsequent open() faults
    in mm_malloc on the corrupted heap (SIGSEGV observed on sim right
    after unregister returns).  With the fix the whole example,
    934706/934706 checks included, completes cleanly.
    
    The test uses only generic configdata APIs, so it also passes
    unchanged under CONFIG_MTD_CONFIG_NVS, whose open/close callbacks
    are no-ops.
    
    Assisted-by: Claude:claude-opus
    Signed-off-by: Arnav Sharma <[email protected]>
---
 examples/configdata/configdata_main.c | 85 +++++++++++++++++++++++++++++++++--
 1 file changed, 81 insertions(+), 4 deletions(-)

diff --git a/examples/configdata/configdata_main.c 
b/examples/configdata/configdata_main.c
index 007a9d162..616c936f9 100644
--- a/examples/configdata/configdata_main.c
+++ b/examples/configdata/configdata_main.c
@@ -342,11 +342,11 @@ static int configdata_fillconfig(void)
             }
 
 #if CONFIG_EXAMPLES_CONFIGDATA_VERBOSE != 0
-         printf("  Created entry %04X, %d  Len=%d\n",
-                entry->id, entry->instance, entry->len);
+          printf("  Created entry %04X, %d  Len=%d\n",
+                 entry->id, entry->instance, entry->len);
 #endif
-         g_nentries++;
-         g_ntotalalloc++;
+          g_nentries++;
+          g_ntotalalloc++;
         }
     }
 
@@ -477,6 +477,7 @@ static int configdata_delentries(void)
   /* Are there any files to be deleted? */
 
   int nentries = g_nentries - g_ndeleted;
+
   if (nentries < 1)
     {
       return 0;
@@ -609,6 +610,80 @@ static void configdata_cleardeleted(void)
   g_ndeleted = 0;
 }
 
+/****************************************************************************
+ * Name: configdata_testunregister
+ *
+ * Description:
+ *   Exercise the /dev/config register/unregister lifetime.  Unregister
+ *   the device, verify that it can no longer be opened, then register
+ *   it again and verify that it is usable.  This is a regression test:
+ *   freeing the private device structure before the temporary file used
+ *   during unregister is closed corrupts the heap and crashes the open
+ *   below.
+ *
+ * Input Parameters:
+ *   mtd - Pointer to the MTD device bound to the /dev/config device
+ *
+ ****************************************************************************/
+
+static void configdata_testunregister(FAR struct mtd_dev_s *mtd)
+{
+  int fd;
+  int ret;
+
+  close(g_fd);
+  g_fd = -1;
+
+  ret = mtdconfig_unregister();
+  if (ret < 0)
+    {
+      printf("ERROR: /dev/config unregistration failed: %d\n", ret);
+      fflush(stdout);
+      exit(3);
+    }
+
+  fd = open("/dev/config", O_RDONLY);
+  if (fd >= 0 || errno != ENOENT)
+    {
+      printf("ERROR: /dev/config still accessible after unregister: "
+             "fd=%d errno=%d\n", fd, errno);
+      fflush(stdout);
+
+      if (fd >= 0)
+        {
+          close(fd);
+        }
+
+      exit(3);
+    }
+
+  ret = mtdconfig_register(mtd);
+  if (ret < 0)
+    {
+      printf("ERROR: /dev/config re-registration failed: %d\n", ret);
+      fflush(stdout);
+      exit(3);
+    }
+
+  fd = open("/dev/config", O_RDONLY);
+  if (fd < 0)
+    {
+      printf("ERROR: Failed to re-open /dev/config %d\n", errno);
+      fflush(stdout);
+      exit(3);
+    }
+
+  close(fd);
+
+  ret = mtdconfig_unregister();
+  if (ret < 0)
+    {
+      printf("ERROR: /dev/config final unregistration failed: %d\n", ret);
+      fflush(stdout);
+      exit(3);
+    }
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -786,6 +861,8 @@ int main(int argc, FAR char *argv[])
   configdata_delallfiles();
 #endif
 
+  configdata_testunregister(mtd);
+
   configdata_endmemusage();
   fflush(stdout);
   return 0;

Reply via email to