From: "Madhavan T. Venkataraman" <madve...@linux.microsoft.com>

Implement the following checks in the unwinder to detect the terminating
frame reliably:

        - The frame must end in task_pt_regs(task)->stackframe.

        - The frame type must be either TASK_FRAME or EL0_FRAME.

Signed-off-by: Madhavan T. Venkataraman <madve...@linux.microsoft.com>
---
 arch/arm64/kernel/stacktrace.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index ad20981dfda4..504cd161339d 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -43,16 +43,22 @@ int notrace unwind_frame(struct task_struct *tsk, struct 
stackframe *frame)
 {
        unsigned long fp = frame->fp;
        struct stack_info info;
+       struct pt_regs *regs;
 
-       /* Terminal record; nothing to unwind */
-       if (!fp)
-               return -ENOENT;
+       if (!tsk)
+               tsk = current;
+       regs = task_pt_regs(tsk);
 
-       if (fp & 0xf)
+       /* Terminal record, nothing to unwind */
+       if (fp == (unsigned long) regs->stackframe) {
+               if (regs->frame_type == TASK_FRAME ||
+                   regs->frame_type == EL0_FRAME)
+                       return -ENOENT;
                return -EINVAL;
+       }
 
-       if (!tsk)
-               tsk = current;
+       if (!fp || fp & 0xf)
+               return -EINVAL;
 
        if (!on_accessible_stack(tsk, fp, &info))
                return -EINVAL;
-- 
2.25.1

Reply via email to