Skip to content

Commit cd96631

Browse files
committed
[nrf fromlist] settings: zms: use the safe function strnlen instead of strlen
if the provided name in argument is not null this could lead to un undefined behavior. Use strnlen to make this safe Upstream PR #: 87792 Signed-off-by: Riadh Ghaddab <[email protected]>
1 parent db05b7c commit cd96631

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

subsys/settings/include/settings/settings_zms.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ extern "C" {
5454
* if a settings element is deleted it won't be found.
5555
*/
5656

57+
#define SETTINGS_FULL_NAME_LEN SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1
58+
5759
#define ZMS_LL_HEAD_HASH_ID 0x80000000
5860
#define ZMS_DATA_ID_OFFSET 0x40000000
5961
#define ZMS_HASH_MASK GENMASK(29, CONFIG_SETTINGS_ZMS_MAX_COLLISIONS_BITS + 1)

subsys/settings/src/settings_zms.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6+
#undef _POSIX_C_SOURCE
7+
#define _POSIX_C_SOURCE 200809L /* for strnlen() */
8+
69
#include <errno.h>
710
#include <string.h>
811

@@ -211,7 +214,7 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
211214
size_t buf_len)
212215
{
213216
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
214-
char r_name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
217+
char r_name[SETTINGS_FULL_NAME_LEN];
215218
ssize_t rc = 0;
216219
uint32_t name_hash;
217220

@@ -220,7 +223,7 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
220223
return -EINVAL;
221224
}
222225

223-
name_hash = sys_hash32(name, strlen(name)) & ZMS_HASH_MASK;
226+
name_hash = sys_hash32(name, strnlen(name, SETTINGS_FULL_NAME_LEN)) & ZMS_HASH_MASK;
224227
for (int i = 0; i <= cf->hash_collision_num; i++) {
225228
name_hash = ZMS_UPDATE_COLLISION_NUM(name_hash, i);
226229
/* Get the name entry from ZMS */
@@ -252,7 +255,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
252255
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
253256
struct settings_zms_read_fn_arg read_fn_arg;
254257
struct settings_hash_linked_list settings_element;
255-
char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
258+
char name[SETTINGS_FULL_NAME_LEN];
256259
ssize_t rc1;
257260
ssize_t rc2;
258261
uint32_t ll_hash_id;
@@ -261,7 +264,9 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
261264

262265
/* If arg->subtree is not null we must load settings in that subtree */
263266
if (arg->subtree != NULL) {
264-
name_hash = sys_hash32(arg->subtree, strlen(arg->subtree)) & ZMS_HASH_MASK;
267+
name_hash =
268+
sys_hash32(arg->subtree, strnlen(arg->subtree, SETTINGS_FULL_NAME_LEN)) &
269+
ZMS_HASH_MASK;
265270
for (int i = 0; i <= cf->hash_collision_num; i++) {
266271
name_hash = ZMS_UPDATE_COLLISION_NUM(name_hash, i);
267272
/* Get the name entry from ZMS */
@@ -423,7 +428,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
423428
/* Find out if we are doing a delete */
424429
delete = ((value == NULL) || (val_len == 0));
425430

426-
name_hash = sys_hash32(name, strlen(name)) & ZMS_HASH_MASK;
431+
name_hash = sys_hash32(name, strnlen(name, SETTINGS_FULL_NAME_LEN)) & ZMS_HASH_MASK;
427432
/* MSB is always 1 */
428433
name_hash |= BIT(31);
429434

@@ -576,7 +581,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
576581
no_ll_update:
577582
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
578583
/* Now let's write the name */
579-
rc = zms_write(&cf->cf_zms, name_hash, name, strlen(name));
584+
rc = zms_write(&cf->cf_zms, name_hash, name, strnlen(name, SETTINGS_FULL_NAME_LEN));
580585
if (rc < 0) {
581586
return rc;
582587
}

0 commit comments

Comments
 (0)