This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b7b3c3c550 arm/backtrace: validate PC register before process unwind
b7b3c3c550 is described below
commit b7b3c3c55067ef5654c69c4076010a6032eb1164
Author: chao an <[email protected]>
AuthorDate: Fri Jun 2 22:08:09 2023 +0800
arm/backtrace: validate PC register before process unwind
Signed-off-by: chao an <[email protected]>
---
arch/arm/src/common/arm_backtrace_unwind.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/arch/arm/src/common/arm_backtrace_unwind.c
b/arch/arm/src/common/arm_backtrace_unwind.c
index 2d37573989..5fc33ff2cb 100644
--- a/arch/arm/src/common/arm_backtrace_unwind.c
+++ b/arch/arm/src/common/arm_backtrace_unwind.c
@@ -538,6 +538,7 @@ nosanitize_address
static int backtrace_unwind(struct unwind_frame_s *frame,
void **buffer, int size, int *skip)
{
+ const struct __EIT_entry *entry;
int cnt = 0;
if (frame->pc && cnt < size && (*skip)-- <= 0)
@@ -550,9 +551,16 @@ static int backtrace_unwind(struct unwind_frame_s *frame,
buffer[cnt++] = (void *)((frame->lr & ~1) - 2);
}
+again:
while (cnt < size)
{
- if (unwind_frame(frame) < 0 || frame->pc == 0)
+ if (unwind_frame(frame) < 0 || frame->pc < 0x10)
+ {
+ break;
+ }
+
+ entry = unwind_find_entry(frame->pc);
+ if (entry == NULL || entry->content == 1)
{
break;
}
@@ -568,6 +576,16 @@ static int backtrace_unwind(struct unwind_frame_s *frame,
}
}
+ if (cnt < size && cnt == 2 && frame->pc != frame->lr)
+ {
+ entry = unwind_find_entry(frame->lr);
+ if (entry != NULL && entry->content != 1)
+ {
+ frame->pc = frame->lr;
+ goto again;
+ }
+ }
+
return cnt > 0 ? cnt : 0;
}
@@ -637,7 +655,7 @@ int up_backtrace(struct tcb_s *tcb,
frame.fp = CURRENT_REGS[REG_FP];
frame.sp = CURRENT_REGS[REG_SP];
frame.pc = CURRENT_REGS[REG_PC];
- frame.lr = 0;
+ frame.lr = CURRENT_REGS[REG_LR];
frame.stack_top = (unsigned long)rtcb->stack_base_ptr +
rtcb->adj_stack_size;
ret += backtrace_unwind(&frame, &buffer[ret],