arm/backtrace: validate PC register before process unwind

Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
chao an 2023-06-02 22:08:09 +08:00 committed by Xiang Xiao
parent 90a34422ed
commit b7b3c3c550

View File

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