From 24e2c520da9bb0d004a0d6336e473350ca5eaf5b Mon Sep 17 00:00:00 2001 From: CYFS <2805686936@qq.com> Date: Thu, 11 Dec 2025 23:54:18 +0800 Subject: [PATCH 1/2] object: add strict name checks guard --- src/Kconfig | 9 +++++++++ src/object.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/Kconfig b/src/Kconfig index ea50610b1f9..008affde36f 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -10,6 +10,15 @@ config RT_NAME_MAX Each kernel object, such as thread, timer, semaphore etc, has a name, the RT_NAME_MAX is the maximal size of this object name. +config RT_USING_STRICT_NAME_CHECKS + bool "Enable strict name checks for kernel objects" + default n + help + Enable duplicate-name detection and strict length checks for kernel + object names. The kernel will refuse to register a new object when its + name already exists in the same class or exceeds RT_NAME_MAX. This + option helps detect configuration mistakes during development. + config RT_USING_ARCH_DATA_TYPE bool "Use the data types defined in ARCH_CPU" default n diff --git a/src/object.c b/src/object.c index 507a47894e1..f87075e5391 100644 --- a/src/object.c +++ b/src/object.c @@ -396,10 +396,28 @@ void rt_object_init(struct rt_object *object, if (name) { obj_name_len = rt_strlen(name); - if(obj_name_len > RT_NAME_MAX - 1) + +#ifdef RT_USING_STRICT_NAME_CHECKS + /* Strict name checks */ + { + rt_object_t duplicate = rt_object_find(name, type); + + if (duplicate) + { + LOG_E("Object name %s already exists in type %d.", name, type); + RT_ASSERT(duplicate == RT_NULL); + } + } +#endif /* RT_USING_STRICT_NAME_CHECKS */ + + if (obj_name_len > RT_NAME_MAX - 1) { LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX); +#ifdef RT_USING_STRICT_NAME_CHECKS + RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1); +#endif /* RT_USING_STRICT_NAME_CHECKS */ } + rt_strncpy(object->name, name, RT_NAME_MAX - 1); object->name[RT_NAME_MAX - 1] = '\0'; } @@ -510,10 +528,27 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name) #if RT_NAME_MAX > 0 if (name) { + +#ifdef RT_USING_STRICT_NAME_CHECKS + /* Strict name checks */ + { + rt_object_t duplicate = rt_object_find(name, type); + + if (duplicate) + { + LOG_E("Object name %s already exists in type %d.", name, type); + RT_ASSERT(duplicate == RT_NULL); + } + } +#endif /* RT_USING_STRICT_NAME_CHECKS */ + obj_name_len = rt_strlen(name); if(obj_name_len > RT_NAME_MAX - 1) { LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX); +#ifdef RT_USING_STRICT_NAME_CHECKS + RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1); +#endif /* RT_USING_STRICT_NAME_CHECKS */ } rt_strncpy(object->name, name, RT_NAME_MAX - 1); object->name[RT_NAME_MAX - 1] = '\0'; @@ -811,4 +846,3 @@ rt_err_t rt_custom_object_destroy(rt_object_t obj) #endif /** @} group_object_management */ - From 39ed842886407c560956d9c305e98d4a40759fa0 Mon Sep 17 00:00:00 2001 From: CYFS <2805686936@qq.com> Date: Fri, 12 Dec 2025 10:02:49 +0800 Subject: [PATCH 2/2] [utest] add strict name-check coverage in object_tc --- src/utest/object_tc.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/utest/object_tc.c b/src/utest/object_tc.c index 2ec54950758..07e787b350c 100644 --- a/src/utest/object_tc.c +++ b/src/utest/object_tc.c @@ -8,6 +8,7 @@ * 2025-07-18 kurisaW First commit * 2025-11-13 CYFS Add standardized documentation block for object_tc * 2025-11-19 Rbb666 Refactor tests, add stress and error-path coverage + * 2025-12-12 CYFS add strict name-check tests */ /** @@ -140,6 +141,30 @@ static rt_err_t generate_unique_name(char *buf, return -RT_ENOMEM; } +#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) +struct strict_assert_capture +{ + rt_bool_t armed; + rt_uint16_t hit_count; + const char *expr; + const char *func; + rt_size_t line; +}; + +static struct strict_assert_capture strict_assert_capture_state; + +static void strict_assert_hook(const char *ex, const char *func, rt_size_t line) +{ + if (!strict_assert_capture_state.armed) + return; + + strict_assert_capture_state.hit_count++; + strict_assert_capture_state.expr = ex; + strict_assert_capture_state.func = func; + strict_assert_capture_state.line = line; +} +#endif /* defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) */ + static void test_object_name_handling(void) { struct rt_object static_obj; @@ -415,6 +440,57 @@ static void test_object_error_paths(void) rt_object_detach(&obj); } +#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) +static void test_object_strict_name_checks(void) +{ + struct rt_object base_obj; + struct rt_object duplicate_obj; + struct rt_object overflow_obj; + char duplicate_name[TEST_RT_NAME_MAX]; + char overflow_name[TEST_RT_NAME_MAX + 8]; + rt_size_t base_len; + void (*prev_hook)(const char *, const char *, rt_size_t) = rt_assert_hook; + + uassert_true(generate_unique_name(duplicate_name, sizeof(duplicate_name), "strict", RT_Object_Class_Thread) == RT_EOK); + rt_object_init(&base_obj, RT_Object_Class_Thread, duplicate_name); + + rt_assert_set_hook(strict_assert_hook); + + strict_assert_capture_state.hit_count = 0; + strict_assert_capture_state.expr = RT_NULL; + strict_assert_capture_state.func = RT_NULL; + strict_assert_capture_state.line = 0; + strict_assert_capture_state.armed = RT_TRUE; + rt_object_init(&duplicate_obj, RT_Object_Class_Thread, duplicate_name); + uassert_true(strict_assert_capture_state.hit_count >= 1); + uassert_not_null(strict_assert_capture_state.expr); + uassert_str_equal(strict_assert_capture_state.expr, "duplicate == RT_NULL"); + strict_assert_capture_state.armed = RT_FALSE; + rt_object_detach(&duplicate_obj); + + uassert_true(generate_unique_name(overflow_name, sizeof(overflow_name), "strict", RT_Object_Class_Thread) == RT_EOK); + base_len = rt_strlen(overflow_name); + rt_memset(overflow_name + base_len, 'x', sizeof(overflow_name) - base_len - 1); + overflow_name[sizeof(overflow_name) - 1] = '\0'; + uassert_true(rt_strlen(overflow_name) > TEST_RT_NAME_MAX - 1); + + strict_assert_capture_state.hit_count = 0; + strict_assert_capture_state.expr = RT_NULL; + strict_assert_capture_state.func = RT_NULL; + strict_assert_capture_state.line = 0; + strict_assert_capture_state.armed = RT_TRUE; + rt_object_init(&overflow_obj, RT_Object_Class_Thread, overflow_name); + uassert_true(strict_assert_capture_state.hit_count >= 1); + uassert_not_null(strict_assert_capture_state.expr); + uassert_str_equal(strict_assert_capture_state.expr, "obj_name_len <= RT_NAME_MAX - 1"); + strict_assert_capture_state.armed = RT_FALSE; + rt_object_detach(&overflow_obj); + + rt_assert_set_hook(prev_hook); + rt_object_detach(&base_obj); +} +#endif /* defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) */ + #ifdef RT_USING_HEAP static rt_err_t custom_destroy_cb(void *data) { @@ -516,6 +592,9 @@ static void test_object_suite(void) UTEST_UNIT_RUN(test_object_error_paths); #ifdef RT_USING_HEAP UTEST_UNIT_RUN(test_custom_object_lifecycle); +#endif +#if defined(RT_USING_STRICT_NAME_CHECKS) && defined(RT_DEBUGING_ASSERT) + UTEST_UNIT_RUN(test_object_strict_name_checks); #endif UTEST_UNIT_RUN(test_object_pressure); }