Skip to content

Commit 3f6a21d

Browse files
Telecaster2147Rbb666
authored andcommitted
fix(finsh): validate backtrace thread address
1 parent 46b90df commit 3f6a21d

3 files changed

Lines changed: 153 additions & 15 deletions

File tree

bsp/hpmicro/hpm6750evk/board/board.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
#include "hpm_enet_drv.h"
2525
#include "hpm_pcfg_drv.h"
2626
#include <rtconfig.h>
27+
#include <rthw.h>
2728

2829
#if defined(ENET_MULTIPLE_PORT) && ENET_MULTIPLE_PORT
2930
#include "hpm_enet_phy_common.h"
30-
#include <rthw.h>
3131
#endif
3232

3333
/**
@@ -88,6 +88,7 @@ __attribute__ ((section(".nor_cfg_option"), used)) const uint32_t option[4] = {0
8888
#endif
8989

9090
#if defined(FLASH_UF2) && FLASH_UF2
91+
/* cppcheck-suppress unknownMacro */
9192
ATTR_PLACE_AT(".uf2_signature") __attribute__((used)) const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;
9293
#endif
9394

@@ -423,7 +424,7 @@ void board_init_i2c(I2C_Type *ptr)
423424
config.is_10bit_addressing = false;
424425
stat = i2c_init_master(ptr, freq, &config);
425426
if (stat != status_success) {
426-
printf("failed to initialize i2c 0x%lx\n", (uint32_t) ptr);
427+
printf("failed to initialize i2c %p\n", (void *)ptr);
427428
while (1) {
428429
}
429430
}
@@ -628,7 +629,7 @@ void board_init_clock(void)
628629
pcfg_dcdc_switch_to_dcm_mode(HPM_PCFG);
629630

630631
if (status_success != pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ)) {
631-
printf("Failed to set pll0_clk0 to %ldHz\n", BOARD_CPU_FREQ);
632+
printf("Failed to set pll0_clk0 to %luHz\n", BOARD_CPU_FREQ);
632633
while (1) {
633634
}
634635
}

bsp/hpmicro/hpm6750evk2/board/board.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
#include "hpm_enet_drv.h"
2525
#include "hpm_pcfg_drv.h"
2626
#include <rtconfig.h>
27+
#include <rthw.h>
2728

2829
#if defined(ENET_MULTIPLE_PORT) && ENET_MULTIPLE_PORT
2930
#include "hpm_enet_phy_common.h"
30-
#include <rthw.h>
3131
#endif
3232

3333
/**
@@ -88,6 +88,7 @@ __attribute__ ((section(".nor_cfg_option"), used)) const uint32_t option[4] = {0
8888
#endif
8989

9090
#if defined(FLASH_UF2) && FLASH_UF2
91+
/* cppcheck-suppress unknownMacro */
9192
ATTR_PLACE_AT(".uf2_signature") __attribute__((used)) const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;
9293
#endif
9394

@@ -423,7 +424,7 @@ void board_init_i2c(I2C_Type *ptr)
423424
config.is_10bit_addressing = false;
424425
stat = i2c_init_master(ptr, freq, &config);
425426
if (stat != status_success) {
426-
printf("failed to initialize i2c 0x%lx\n", (uint32_t) ptr);
427+
printf("failed to initialize i2c %p\n", (void *)ptr);
427428
while (1) {
428429
}
429430
}
@@ -628,7 +629,7 @@ void board_init_clock(void)
628629
pcfg_dcdc_switch_to_dcm_mode(HPM_PCFG);
629630

630631
if (status_success != pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ)) {
631-
printf("Failed to set pll0_clk0 to %ldHz\n", BOARD_CPU_FREQ);
632+
printf("Failed to set pll0_clk0 to %luHz\n", BOARD_CPU_FREQ);
632633
while (1) {
633634
}
634635
}

src/kservice.c

Lines changed: 145 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,10 @@ RTM_EXPORT(rt_kprintf);
430430
*/
431431
rt_weak rt_err_t rt_backtrace(void)
432432
{
433-
struct rt_hw_backtrace_frame frame;
433+
struct rt_hw_backtrace_frame frame = {0};
434434
rt_thread_t thread = rt_thread_self();
435435

436+
/* cppcheck-suppress uninitvar */
436437
RT_HW_BACKTRACE_FRAME_GET_SELF(&frame);
437438
if (!frame.fp)
438439
return -RT_EINVAL;
@@ -511,7 +512,7 @@ rt_weak rt_err_t rt_backtrace_to_buffer(rt_thread_t thread,
511512
long buflen)
512513
{
513514
long nesting = 0;
514-
struct rt_hw_backtrace_frame cur_frame;
515+
struct rt_hw_backtrace_frame cur_frame = {0};
515516

516517
if (!thread)
517518
return -RT_EINVAL;
@@ -521,6 +522,7 @@ rt_weak rt_err_t rt_backtrace_to_buffer(rt_thread_t thread,
521522
if (!frame)
522523
{
523524
frame = &cur_frame;
525+
/* cppcheck-suppress uninitvar */
524526
RT_HW_BACKTRACE_FRAME_GET_SELF(frame);
525527
if (!frame->fp)
526528
return -RT_EINVAL;
@@ -745,12 +747,133 @@ rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
745747
#endif /* RT_USING_CPU_USAGE_TRACER */
746748

747749
#if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
750+
#include <limits.h>
748751
#include <stdlib.h> /* for string service */
749752

750-
static void cmd_backtrace(int argc, char** argv)
753+
struct cmd_backtrace_find_ctx
751754
{
752755
rt_uintptr_t pid;
756+
rt_thread_t thread;
757+
};
758+
759+
static rt_err_t cmd_backtrace_match_thread(struct rt_object *object, void *data)
760+
{
761+
struct cmd_backtrace_find_ctx *ctx = data;
762+
763+
if ((rt_uintptr_t)object == ctx->pid)
764+
{
765+
ctx->thread = (rt_thread_t)object;
766+
767+
return 1;
768+
}
769+
770+
return RT_EOK;
771+
}
772+
773+
#if UINTPTR_MAX > ULONG_MAX
774+
static void cmd_backtrace_format_pid(rt_uintptr_t pid, char *buf, rt_size_t size)
775+
{
776+
static const char hex[] = "0123456789abcdef";
777+
char digits[sizeof(rt_uintptr_t) * 2];
778+
rt_size_t count = 0;
779+
rt_size_t index;
780+
781+
if ((buf == RT_NULL) || (size < 4))
782+
{
783+
if ((buf != RT_NULL) && (size > 0))
784+
{
785+
buf[0] = '\0';
786+
}
787+
return;
788+
}
789+
790+
do
791+
{
792+
digits[count++] = hex[pid & 0xf];
793+
pid >>= 4;
794+
}
795+
while ((pid != 0) && (count < sizeof(digits)));
796+
797+
buf[0] = '0';
798+
buf[1] = 'x';
799+
800+
for (index = 0; index < count; index++)
801+
{
802+
buf[2 + index] = digits[count - index - 1];
803+
}
804+
805+
buf[2 + count] = '\0';
806+
}
807+
#endif
808+
809+
static rt_bool_t cmd_backtrace_parse_pid(const char *arg, rt_uintptr_t *pid)
810+
{
753811
char *end_ptr;
812+
#if UINTPTR_MAX > ULONG_MAX
813+
unsigned long long parsed_value;
814+
#else
815+
unsigned long parsed_value;
816+
#endif
817+
rt_uintptr_t value;
818+
819+
if ((arg == RT_NULL) || (pid == RT_NULL))
820+
{
821+
return RT_FALSE;
822+
}
823+
824+
if ((*arg == '+') || (*arg == '-'))
825+
{
826+
return RT_FALSE;
827+
}
828+
829+
errno = 0;
830+
#if UINTPTR_MAX > ULONG_MAX
831+
parsed_value = strtoull(arg, &end_ptr, 0);
832+
#else
833+
parsed_value = strtoul(arg, &end_ptr, 0);
834+
#endif
835+
if ((end_ptr == arg) || (*end_ptr != '\0') ||
836+
(errno == ERANGE) ||
837+
#if UINTPTR_MAX > ULONG_MAX
838+
(parsed_value > (unsigned long long)(rt_uintptr_t)-1))
839+
#else
840+
(parsed_value > (unsigned long)(rt_uintptr_t)-1))
841+
#endif
842+
{
843+
return RT_FALSE;
844+
}
845+
846+
value = (rt_uintptr_t)parsed_value;
847+
if (value == 0)
848+
{
849+
return RT_FALSE;
850+
}
851+
852+
*pid = value;
853+
854+
return RT_TRUE;
855+
}
856+
857+
static rt_thread_t cmd_backtrace_find_thread(rt_uintptr_t pid)
858+
{
859+
struct cmd_backtrace_find_ctx ctx =
860+
{
861+
.pid = pid,
862+
.thread = RT_NULL,
863+
};
864+
865+
rt_object_for_each(RT_Object_Class_Thread, cmd_backtrace_match_thread, &ctx);
866+
867+
return ctx.thread;
868+
}
869+
870+
static void cmd_backtrace(int argc, char** argv)
871+
{
872+
rt_uintptr_t pid;
873+
rt_thread_t target;
874+
#if UINTPTR_MAX > ULONG_MAX
875+
char pid_buf[sizeof(rt_uintptr_t) * 2 + 3];
876+
#endif
754877

755878
if (argc != 2)
756879
{
@@ -770,21 +893,34 @@ static void cmd_backtrace(int argc, char** argv)
770893
}
771894
}
772895

773-
pid = strtoul(argv[1], &end_ptr, 0);
774-
if (end_ptr == argv[1])
896+
if (!cmd_backtrace_parse_pid(argv[1], &pid))
775897
{
776898
rt_kprintf("Invalid input: %s\n", argv[1]);
777899
return ;
778900
}
779901

780-
if (pid && rt_object_get_type((void *)pid) == RT_Object_Class_Thread)
902+
target = cmd_backtrace_find_thread(pid);
903+
#if UINTPTR_MAX > ULONG_MAX
904+
cmd_backtrace_format_pid(pid, pid_buf, sizeof(pid_buf));
905+
#endif
906+
if (target != RT_NULL)
781907
{
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]);
908+
#if UINTPTR_MAX > ULONG_MAX
909+
rt_kprintf("backtrace %s(%s), from %s\n", target->parent.name, pid_buf, argv[1]);
910+
#else
911+
rt_kprintf("backtrace %s(0x%lx), from %s\n",
912+
target->parent.name, (unsigned long)pid, argv[1]);
913+
#endif
784914
rt_backtrace_thread(target);
785915
}
786916
else
787-
rt_kprintf("Invalid pid: %ld\n", pid);
917+
{
918+
#if UINTPTR_MAX > ULONG_MAX
919+
rt_kprintf("Invalid pid: %s\n", pid_buf);
920+
#else
921+
rt_kprintf("Invalid pid: %lx\n", (unsigned long)pid);
922+
#endif
923+
}
788924
}
789925
MSH_CMD_EXPORT_ALIAS(cmd_backtrace, backtrace, print backtrace of a thread);
790926

0 commit comments

Comments
 (0)