arm/backtrace: validate PC register before process unwind
Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
parent
90a34422ed
commit
b7b3c3c550
@ -538,6 +538,7 @@ nosanitize_address
|
|||||||
static int backtrace_unwind(struct unwind_frame_s *frame,
|
static int backtrace_unwind(struct unwind_frame_s *frame,
|
||||||
void **buffer, int size, int *skip)
|
void **buffer, int size, int *skip)
|
||||||
{
|
{
|
||||||
|
const struct __EIT_entry *entry;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
if (frame->pc && cnt < size && (*skip)-- <= 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);
|
buffer[cnt++] = (void *)((frame->lr & ~1) - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
while (cnt < size)
|
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;
|
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;
|
return cnt > 0 ? cnt : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +655,7 @@ int up_backtrace(struct tcb_s *tcb,
|
|||||||
frame.fp = CURRENT_REGS[REG_FP];
|
frame.fp = CURRENT_REGS[REG_FP];
|
||||||
frame.sp = CURRENT_REGS[REG_SP];
|
frame.sp = CURRENT_REGS[REG_SP];
|
||||||
frame.pc = CURRENT_REGS[REG_PC];
|
frame.pc = CURRENT_REGS[REG_PC];
|
||||||
frame.lr = 0;
|
frame.lr = CURRENT_REGS[REG_LR];
|
||||||
frame.stack_top = (unsigned long)rtcb->stack_base_ptr +
|
frame.stack_top = (unsigned long)rtcb->stack_base_ptr +
|
||||||
rtcb->adj_stack_size;
|
rtcb->adj_stack_size;
|
||||||
ret += backtrace_unwind(&frame, &buffer[ret],
|
ret += backtrace_unwind(&frame, &buffer[ret],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user