Skip to content

Commit 5b7311d

Browse files
rghaddabcarlescufi
authored andcommitted
[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]> (cherry picked from commit e9ac2ef95bd34a8c4756e46e8f2ddf66e0964dbc) (cherry picked from commit 4efae76)
1 parent 2b3ab07 commit 5b7311d

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

include/zephyr/settings/settings.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ extern "C" {
4545
*/
4646
#define SETTINGS_EXTRA_LEN ((SETTINGS_MAX_DIR_DEPTH - 1) + 2)
4747

48+
/* Maximum Settings name length including separators */
49+
#define SETTINGS_FULL_NAME_LEN SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1
50+
4851
/**
4952
* Function used to read the data from the settings storage in
5053
* h_set handler implementations.

subsys/settings/src/settings_zms.c

+14-10
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

@@ -169,12 +172,13 @@ static int settings_zms_load_subtree(struct settings_store *cs, const struct set
169172
{
170173
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
171174
struct settings_zms_read_fn_arg read_fn_arg;
172-
char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
175+
char name[SETTINGS_FULL_NAME_LEN];
173176
ssize_t rc1;
174177
ssize_t rc2;
175178
uint32_t name_hash;
176179

177-
name_hash = sys_hash32(arg->subtree, strlen(arg->subtree)) & ZMS_HASH_MASK;
180+
name_hash = sys_hash32(arg->subtree, strnlen(arg->subtree, SETTINGS_FULL_NAME_LEN)) &
181+
ZMS_HASH_MASK;
178182
for (int i = 0; i <= cf->hash_collision_num; i++) {
179183
name_hash = ZMS_UPDATE_COLLISION_NUM(name_hash, i);
180184
/* Get the name entry from ZMS */
@@ -214,7 +218,7 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
214218
size_t buf_len)
215219
{
216220
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
217-
char r_name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
221+
char r_name[SETTINGS_FULL_NAME_LEN];
218222
ssize_t rc = 0;
219223
uint32_t name_hash;
220224
uint32_t value_id;
@@ -224,7 +228,7 @@ static ssize_t settings_zms_load_one(struct settings_store *cs, const char *name
224228
return -EINVAL;
225229
}
226230

227-
name_hash = sys_hash32(name, strlen(name)) & ZMS_HASH_MASK;
231+
name_hash = sys_hash32(name, strnlen(name, SETTINGS_FULL_NAME_LEN)) & ZMS_HASH_MASK;
228232
for (int i = 0; i <= cf->hash_collision_num; i++) {
229233
name_hash = ZMS_UPDATE_COLLISION_NUM(name_hash, i);
230234
/* Get the name entry from ZMS */
@@ -259,7 +263,7 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
259263
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
260264
struct settings_zms_read_fn_arg read_fn_arg;
261265
struct settings_hash_linked_list settings_element;
262-
char name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
266+
char name[SETTINGS_FULL_NAME_LEN];
263267
ssize_t rc1;
264268
ssize_t rc2;
265269
uint32_t ll_hash_id;
@@ -380,7 +384,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
380384
{
381385
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
382386
struct settings_hash_linked_list settings_element;
383-
char rdname[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
387+
char rdname[SETTINGS_FULL_NAME_LEN];
384388
uint32_t name_hash;
385389
uint32_t collision_num = 0;
386390
bool delete;
@@ -396,7 +400,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
396400
/* Find out if we are doing a delete */
397401
delete = ((value == NULL) || (val_len == 0));
398402

399-
name_hash = sys_hash32(name, strlen(name)) & ZMS_HASH_MASK;
403+
name_hash = sys_hash32(name, strnlen(name, SETTINGS_FULL_NAME_LEN)) & ZMS_HASH_MASK;
400404
/* MSB is always 1 */
401405
name_hash |= BIT(31);
402406

@@ -523,7 +527,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
523527
no_ll_update:
524528
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
525529
/* Now let's write the name */
526-
rc = zms_write(&cf->cf_zms, name_hash, name, strlen(name));
530+
rc = zms_write(&cf->cf_zms, name_hash, name, strnlen(name, SETTINGS_FULL_NAME_LEN));
527531
if (rc < 0) {
528532
return rc;
529533
}
@@ -534,7 +538,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
534538
static ssize_t settings_zms_get_val_len(struct settings_store *cs, const char *name)
535539
{
536540
struct settings_zms *cf = CONTAINER_OF(cs, struct settings_zms, cf_store);
537-
char r_name[SETTINGS_MAX_NAME_LEN + SETTINGS_EXTRA_LEN + 1];
541+
char r_name[SETTINGS_FULL_NAME_LEN];
538542
ssize_t rc = 0;
539543
uint32_t name_hash;
540544

@@ -543,7 +547,7 @@ static ssize_t settings_zms_get_val_len(struct settings_store *cs, const char *n
543547
return -EINVAL;
544548
}
545549

546-
name_hash = sys_hash32(name, strlen(name)) & ZMS_HASH_MASK;
550+
name_hash = sys_hash32(name, strnlen(name, SETTINGS_FULL_NAME_LEN)) & ZMS_HASH_MASK;
547551
for (int i = 0; i <= cf->hash_collision_num; i++) {
548552
name_hash = ZMS_UPDATE_COLLISION_NUM(name_hash, i);
549553
/* Get the name entry from ZMS */

0 commit comments

Comments
 (0)