From 9e20b41f19da27ec02f558ce1d6a33acc8ece55c Mon Sep 17 00:00:00 2001 From: wangzhi16 Date: Fri, 21 Feb 2025 17:49:25 +0800 Subject: [PATCH] note/drivers: Get taskname more safely. When tcb may has been released in caller, the return pointer to tcb->name is dangling pointer. So add a buffer in caller, even if tcb is released, buffer is still valid. Signed-off-by: wangzhi16 --- drivers/note/note_driver.c | 43 ++++++++++++++------------ drivers/note/noteram_driver.c | 53 ++++++++++++++++---------------- include/nuttx/note/note_driver.h | 13 +++----- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/drivers/note/note_driver.c b/drivers/note/note_driver.c index 71cc45b33ed..140f08b48c6 100644 --- a/drivers/note/note_driver.c +++ b/drivers/note/note_driver.c @@ -2085,8 +2085,6 @@ void sched_note_filter_tag(FAR struct note_filter_named_tag_s *oldf, #endif /* CONFIG_SCHED_INSTRUMENTATION_FILTER */ -#if CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0 - /**************************************************************************** * Name: note_get_taskname * @@ -2095,38 +2093,45 @@ void sched_note_filter_tag(FAR struct note_filter_named_tag_s *oldf, * * Input Parameters: * PID - Task ID + * buf - A writable buffer to hold the task name + * len - The length of the buffer * * Returned Value: - * Return name if task name can be retrieved, otherwise NULL + * None + * ****************************************************************************/ -FAR const char *note_get_taskname(pid_t pid) +void note_get_taskname(pid_t pid, FAR char *buf, size_t len) { - FAR struct note_taskname_info_s *ti; - FAR struct tcb_s *tcb; - UNUSED(ti); +#if CONFIG_TASK_NAME_SIZE > 0 + FAR struct tcb_s *tcb = nxsched_get_tcb(pid); - tcb = nxsched_get_tcb(pid); if (tcb != NULL) { - return tcb->name; + strlcpy(buf, tcb->name, len); } - -#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH - ti = note_find_taskname(pid); - if (ti != NULL) + else { - return ti->name; - } +# ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH + FAR struct note_taskname_info_s *ti = note_find_taskname(pid); - return NULL; + if (ti != NULL) + { + strlcpy(buf, tcb->name, len); + } + else + { + strlcpy(buf, "", len); + } +# else + strlcpy(buf, "", len); +# endif + } #else - return "unknown"; + strlcpy(buf, "", len); #endif } -#endif - /**************************************************************************** * Name: note_driver_register ****************************************************************************/ diff --git a/drivers/note/noteram_driver.c b/drivers/note/noteram_driver.c index 3464e5e0719..246483d27f2 100644 --- a/drivers/note/noteram_driver.c +++ b/drivers/note/noteram_driver.c @@ -72,6 +72,12 @@ #define get_task_state(s) \ ((s) == 0 ? 'X' : ((s) <= LAST_READY_TO_RUN_STATE ? 'R' : 'S')) +#if CONFIG_TASK_NAME_SIZE > 0 +# define TASK_NAME_SIZE (CONFIG_TASK_NAME_SIZE + 1) +#else +# define TASK_NAME_SIZE 16 +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -763,25 +769,6 @@ static void noteram_dump_init_context(FAR struct noteram_dump_context_s *ctx) } } -/**************************************************************************** - * Name: get_taskname - ****************************************************************************/ - -static const char *get_taskname(pid_t pid) -{ -#if CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0 - FAR const char *taskname; - - taskname = note_get_taskname(pid); - if (taskname != NULL) - { - return taskname; - } -#endif - - return ""; -} - /**************************************************************************** * Name: noteram_dump_header ****************************************************************************/ @@ -791,6 +778,7 @@ static int noteram_dump_header(FAR struct lib_outstream_s *s, FAR struct noteram_dump_context_s *ctx) { struct timespec ts; + char buf[TASK_NAME_SIZE]; pid_t pid; int ret; @@ -802,8 +790,10 @@ static int noteram_dump_header(FAR struct lib_outstream_s *s, int cpu = 0; #endif + note_get_taskname(pid, buf, TASK_NAME_SIZE); + ret = lib_sprintf(s, "%8s-%-3u [%d] %3" PRIu64 ".%09lu: ", - get_taskname(pid), get_pid(pid), cpu, + buf, get_pid(pid), cpu, (uint64_t)ts.tv_sec, ts.tv_nsec); return ret; @@ -820,6 +810,8 @@ static int noteram_dump_sched_switch(FAR struct lib_outstream_s *s, FAR struct noteram_dump_context_s *ctx) { FAR struct noteram_dump_cpu_context_s *cctx; + char current_buf[TASK_NAME_SIZE]; + char next_buf[TASK_NAME_SIZE]; uint8_t current_priority; uint8_t next_priority; pid_t current_pid; @@ -838,12 +830,15 @@ static int noteram_dump_sched_switch(FAR struct lib_outstream_s *s, current_priority = cctx->current_priority; next_priority = cctx->next_priority; + note_get_taskname(current_pid, current_buf, TASK_NAME_SIZE); + note_get_taskname(next_pid, next_buf, TASK_NAME_SIZE); + ret = lib_sprintf(s, "sched_switch: prev_comm=%s prev_pid=%u " "prev_prio=%u prev_state=%c ==> " "next_comm=%s next_pid=%u next_prio=%u\n", - get_taskname(current_pid), get_pid(current_pid), + current_buf, get_pid(current_pid), current_priority, get_task_state(cctx->current_state), - get_taskname(next_pid), get_pid(next_pid), + next_buf, get_pid(next_pid), next_priority); cctx->current_pid = cctx->next_pid; @@ -921,13 +916,16 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, { FAR struct note_common_s *note = (FAR struct note_common_s *)p; FAR struct noteram_dump_cpu_context_s *cctx; - int ret = 0; - pid_t pid; +#ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH + char buf[TASK_NAME_SIZE]; +#endif #ifdef CONFIG_SMP int cpu = note->nc_cpu; #else int cpu = 0; #endif + int ret = 0; + pid_t pid; cctx = &ctx->cpu[cpu]; pid = note->nc_pid; @@ -944,10 +942,11 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, #ifdef CONFIG_SCHED_INSTRUMENTATION_SWITCH case NOTE_START: { + note_get_taskname(pid, buf, TASK_NAME_SIZE); ret += noteram_dump_header(s, note, ctx); ret += lib_sprintf(s, "sched_wakeup_new: comm=%s pid=%d " "target_cpu=%d\n", - get_taskname(pid), get_pid(pid), cpu); + buf, get_pid(pid), cpu); } break; @@ -997,11 +996,11 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s, * until leaving the interrupt handler. */ + note_get_taskname(cctx->next_pid, buf, TASK_NAME_SIZE); ret += noteram_dump_header(s, note, ctx); ret += lib_sprintf(s, "sched_waking: comm=%s " "pid=%d target_cpu=%d\n", - get_taskname(cctx->next_pid), - get_pid(cctx->next_pid), cpu); + buf, get_pid(cctx->next_pid), cpu); cctx->pendingswitch = true; } } diff --git a/include/nuttx/note/note_driver.h b/include/nuttx/note/note_driver.h index 9b8496cf6f6..54bf87d9f47 100644 --- a/include/nuttx/note/note_driver.h +++ b/include/nuttx/note/note_driver.h @@ -179,9 +179,6 @@ int note_initialize(void); #endif /* defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT) */ -#if defined(CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE) && \ - CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0 - /**************************************************************************** * Name: note_get_taskname * @@ -190,17 +187,15 @@ int note_initialize(void); * * Input Parameters: * PID - Task ID + * buf - A writable buffer to hold the task name + * len - The length of the buffer * * Returned Value: - * Return name if task name can be retrieved, otherwise NULL + * None * ****************************************************************************/ -FAR const char *note_get_taskname(pid_t pid); - -#endif /* defined(CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE) && \ - * CONFIG_DRIVERS_NOTE_TASKNAME_BUFSIZE > 0 - */ +void note_get_taskname(pid_t pid, FAR char *buf, size_t len); /**************************************************************************** * Name: note_driver_register