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

Reply via email to