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

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

commit c0fc20820288c541935fd02a2d9c1ce4d940ba4f
Author: Nightt <[email protected]>
AuthorDate: Wed May 27 17:18:35 2026 +0800

    system/settings: Bound storage string handling
    
    Use configured key, value, and filename limits while loading and saving 
settings storage data.
    
    The text backend now builds backup filenames with a sized buffer and 
bounded formatting, and both text and binary loading reject keys or string 
values that are not terminated within their configured field sizes. This 
completes #3109 without changing the storage formats.
    
    Signed-off-by: Nightt <[email protected]>
---
 system/settings/storage_bin.c  | 16 ++++++++++++++-
 system/settings/storage_text.c | 44 ++++++++++++++++++++++++++++--------------
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/system/settings/storage_bin.c b/system/settings/storage_bin.c
index dff17f6fa..b2b37443e 100644
--- a/system/settings/storage_bin.c
+++ b/system/settings/storage_bin.c
@@ -96,12 +96,19 @@ extern setting_t map[CONFIG_SYSTEM_SETTINGS_MAP_SIZE];
 FAR setting_t *getsetting(FAR char *key)
 {
   int i;
+  size_t keylen;
+
+  keylen = strnlen(key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
+  if (keylen >= CONFIG_SYSTEM_SETTINGS_KEY_SIZE)
+    {
+      return NULL;
+    }
 
   for (i = 0; i < CONFIG_SYSTEM_SETTINGS_MAP_SIZE; i++)
     {
       FAR setting_t *setting = &map[i];
 
-      if (strcmp(key, setting->key) == 0)
+      if (strncmp(key, setting->key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE) == 0)
         {
           return setting;
         }
@@ -190,6 +197,13 @@ int load_bin(FAR char *file)
           continue;
         }
 
+      if (setting.type == SETTING_STRING &&
+          strnlen(setting.val.s, CONFIG_SYSTEM_SETTINGS_VALUE_SIZE) >=
+          CONFIG_SYSTEM_SETTINGS_VALUE_SIZE)
+        {
+          continue;
+        }
+
       memcpy(slot, &setting, sizeof(setting_t));
     }
 
diff --git a/system/settings/storage_text.c b/system/settings/storage_text.c
index de48a60a2..dcf0b0fac 100644
--- a/system/settings/storage_text.c
+++ b/system/settings/storage_text.c
@@ -97,9 +97,11 @@ extern setting_t map[CONFIG_SYSTEM_SETTINGS_MAP_SIZE];
 FAR setting_t *getsetting(char *key)
 {
   int i;
+  size_t keylen;
   FAR setting_t *setting;
 
-  if (strlen(key) >= CONFIG_SYSTEM_SETTINGS_KEY_SIZE)
+  keylen = strnlen(key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
+  if (keylen >= CONFIG_SYSTEM_SETTINGS_KEY_SIZE)
     {
       return NULL;
     }
@@ -108,15 +110,14 @@ FAR setting_t *getsetting(char *key)
     {
       setting = &map[i];
 
-      if (strcmp(key, setting->key) == 0)
+      if (strncmp(key, setting->key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE) == 0)
         {
           return setting;
         }
 
       if (setting->type == SETTING_EMPTY)
         {
-          strncpy(setting->key, key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
-          setting->key[CONFIG_SYSTEM_SETTINGS_KEY_SIZE - 1] = '\0';
+          strlcpy(setting->key, key, CONFIG_SYSTEM_SETTINGS_KEY_SIZE);
           return setting;
         }
     }
@@ -152,21 +153,27 @@ int load_text(FAR char *file)
   FAR char      *backup_file;
   FAR char      *buffer;
   FAR setting_t *setting;
+  size_t        filelen;
 
   /* Check that the file exists */
 
+  filelen = strnlen(file, CONFIG_SYSTEM_SETTINGS_MAX_FILENAME);
+  if (filelen >= CONFIG_SYSTEM_SETTINGS_MAX_FILENAME)
+    {
+      return -EINVAL;
+    }
+
   if (access(file, F_OK) != 0)
     {
       /* If not, try the backup file */
 
-      backup_file = malloc(strlen(file) + 2);
+      backup_file = malloc(filelen + 2);
       if (backup_file == NULL)
         {
           return -ENODEV;
         }
 
-      strcpy(backup_file, file);
-      strcat(backup_file, "~");
+      snprintf(backup_file, filelen + 2, "%s~", file);
 
       if (access(backup_file, F_OK) == 0)
         {
@@ -196,10 +203,12 @@ int load_text(FAR char *file)
   while (fgets(buffer, BUFFER_SIZE, f))
     {
       int  i;
+      size_t linelen;
 
       /* Remove any line terminators */
 
-      for (i = ((int)strlen(buffer) - 1); i > 0; i--)
+      linelen = strnlen(buffer, BUFFER_SIZE);
+      for (i = ((int)linelen - 1); i > 0; i--)
         {
           if (buffer[i] == ';' || buffer[i] == '\n' || buffer[i] == '\r')
             {
@@ -260,15 +269,15 @@ int load_text(FAR char *file)
             {
               /* It's a string */
 
-              if (strlen(val) >= CONFIG_SYSTEM_SETTINGS_VALUE_SIZE)
+              if (strnlen(val, CONFIG_SYSTEM_SETTINGS_VALUE_SIZE) >=
+                  CONFIG_SYSTEM_SETTINGS_VALUE_SIZE)
                 {
                   continue;
                 }
 
               setting->type = SETTING_STRING;
-              strncpy(setting->val.s, val,
+              strlcpy(setting->val.s, val,
                       CONFIG_SYSTEM_SETTINGS_VALUE_SIZE);
-              setting->val.s[CONFIG_SYSTEM_SETTINGS_VALUE_SIZE - 1] = '\0';
             }
         }
       else
@@ -343,17 +352,24 @@ abort:
 int save_text(FAR char *file)
 {
   int      ret = OK;
-  FAR char *backup_file = malloc(strlen(file) + 2);
+  FAR char *backup_file;
   FAR FILE *f;
+  size_t   filelen;
   int      i;
 
+  filelen = strnlen(file, CONFIG_SYSTEM_SETTINGS_MAX_FILENAME);
+  if (filelen >= CONFIG_SYSTEM_SETTINGS_MAX_FILENAME)
+    {
+      return -EINVAL;
+    }
+
+  backup_file = malloc(filelen + 2);
   if (backup_file == NULL)
     {
       return -ENODEV;
     }
 
-  strcpy(backup_file, file);
-  strcat(backup_file, "~");
+  snprintf(backup_file, filelen + 2, "%s~", file);
 
   f = fopen(backup_file, "w");
   if (f == NULL)

Reply via email to