Skip to content

Commit c540775

Browse files
fix(finsh): validate backtrace thread address
1 parent fa0a61c commit c540775

1 file changed

Lines changed: 62 additions & 7 deletions

File tree

src/kservice.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -747,10 +747,64 @@ rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
747747
#if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
748748
#include <stdlib.h> /* for string service */
749749

750-
static void cmd_backtrace(int argc, char** argv)
750+
struct cmd_backtrace_find_ctx
751751
{
752752
rt_uintptr_t pid;
753+
rt_thread_t thread;
754+
};
755+
756+
static rt_err_t cmd_backtrace_match_thread(struct rt_object *object, void *data)
757+
{
758+
struct cmd_backtrace_find_ctx *ctx = data;
759+
760+
if ((rt_uintptr_t)object == ctx->pid)
761+
{
762+
ctx->thread = (rt_thread_t)object;
763+
764+
return 1;
765+
}
766+
767+
return RT_EOK;
768+
}
769+
770+
static rt_bool_t cmd_backtrace_parse_pid(const char *arg, rt_uintptr_t *pid)
771+
{
753772
char *end_ptr;
773+
rt_uintptr_t value;
774+
775+
if ((arg == RT_NULL) || (pid == RT_NULL))
776+
{
777+
return RT_FALSE;
778+
}
779+
780+
value = (rt_uintptr_t)strtoul(arg, &end_ptr, 0);
781+
if ((end_ptr == arg) || (*end_ptr != '\0') || (value == 0))
782+
{
783+
return RT_FALSE;
784+
}
785+
786+
*pid = value;
787+
788+
return RT_TRUE;
789+
}
790+
791+
static rt_thread_t cmd_backtrace_find_thread(rt_uintptr_t pid)
792+
{
793+
struct cmd_backtrace_find_ctx ctx =
794+
{
795+
.pid = pid,
796+
.thread = RT_NULL,
797+
};
798+
799+
rt_object_for_each(RT_Object_Class_Thread, cmd_backtrace_match_thread, &ctx);
800+
801+
return ctx.thread;
802+
}
803+
804+
static void cmd_backtrace(int argc, char** argv)
805+
{
806+
rt_uintptr_t pid;
807+
rt_thread_t target;
754808

755809
if (argc != 2)
756810
{
@@ -770,21 +824,22 @@ static void cmd_backtrace(int argc, char** argv)
770824
}
771825
}
772826

773-
pid = strtoul(argv[1], &end_ptr, 0);
774-
if (end_ptr == argv[1])
827+
if (!cmd_backtrace_parse_pid(argv[1], &pid))
775828
{
776829
rt_kprintf("Invalid input: %s\n", argv[1]);
777830
return ;
778831
}
779832

780-
if (pid && rt_object_get_type((void *)pid) == RT_Object_Class_Thread)
833+
target = cmd_backtrace_find_thread(pid);
834+
if (target != RT_NULL)
781835
{
782-
rt_thread_t target = (rt_thread_t)pid;
783-
rt_kprintf("backtrace %s(0x%lx), from %s\n", target->parent.name, pid, argv[1]);
836+
rt_kprintf("backtrace %s(0x%lx), from %s\n", target->parent.name, (unsigned long)pid, argv[1]);
784837
rt_backtrace_thread(target);
785838
}
786839
else
787-
rt_kprintf("Invalid pid: %ld\n", pid);
840+
{
841+
rt_kprintf("Invalid pid: %lx\n", (unsigned long)pid);
842+
}
788843
}
789844
MSH_CMD_EXPORT_ALIAS(cmd_backtrace, backtrace, print backtrace of a thread);
790845

0 commit comments

Comments
 (0)