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 <wangzhi16@xiaomi.com>
This commit is contained in:
wangzhi16 2025-02-21 17:49:25 +08:00 committed by Xiang Xiao
parent 86a07ffac1
commit 9e20b41f19
3 changed files with 54 additions and 55 deletions

View file

@ -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, "<noname>", len);
}
# else
strlcpy(buf, "<noname>", len);
# endif
}
#else
return "unknown";
strlcpy(buf, "<noname>", len);
#endif
}
#endif
/****************************************************************************
* Name: note_driver_register
****************************************************************************/

View file

@ -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 "<noname>";
}
/****************************************************************************
* 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;
}
}

View file

@ -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