Date: Wed, 7 Jun 2023 18:37:34 +0900
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
To: crash-utility@redhat.com
Cc: d.hatayama@fujitsu.com
Subject: [Crash-utility] [PATCH 2/2] Fix again segfault in
arm64_is_kernel_exception_frame() when corrupt stack pointer address
is given
Message-ID: <20230607093734.247-2-d.hatayama@fujitsu.com>
Content-Type: text/plain; charset="US-ASCII"; x-default=true
This is the second trial from the commit
9868ebc8e648e5791764a51567a23efae7170d9b that was reverted at the
previous commit.
As described in the previous commit, result of STACK_OFFSET_TYPE() can
be an address out of bt->stackbuf and hence the address needs to be
checked prior to being referred to as an pt_regs object.
So, to fix the issue, let's check if stkptr points to within the range
of the kernel stack first.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
---
arm64.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arm64.c b/arm64.c
index efbdccb..ca63fb5 100644
--- a/arm64.c
+++ b/arm64.c
@@ -2381,6 +2381,9 @@ arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
struct arm64_pt_regs *regs;
struct machine_specific *ms = machdep->machspec;
+ if (stkptr > STACKSIZE() && !INSTACK(stkptr, bt))
+ return FALSE;
+
I still have one question: Why does this one only need to be fixed, but the others are not needed(it won't be out of range)? The STACK_OFFSET_TYPE() is invoked multiple times in arm64.c, and similar calls can be seen on other arches(grep -nr "GET_STACK_ULONG" *.c or grep -nr "GET_STACK_DATA" *.c).
# grep -nr "STACK_OFFSET_TYPE" *.c
arm64.c:2384: regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];
arm64.c:2821: ptregs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(orig_sp))];
arm64.c:3476: base = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(bt->stackbase))];
arm64.c:3478: start = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(bt->stacktop))];
arm64.c:3481: start = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(frame->fp))];
arm64.c:3483: start = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(bt->stacktop))];
arm64.c:3801: &bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(sp))];
arm64.c:3822: &bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(pt_regs))];
x86.c:1075: if (STACK_OFFSET_TYPE(ep->eframe_addr) > STACKSIZE())
[root@hpe-apollo-cn99xx-13-vm-01 crash]# grep -nr "STACK_OFFSET_TYPE" *.h
defs.h:977:#define STACK_OFFSET_TYPE(OFF) \
defs.h:985: *((ulong *)((char *)(&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(OFF))])))
defs.h:988: (void *)(&bt->stackbuf[(ulong)STACK_OFFSET_TYPE(OFF)]), (size_t)(SZ))
Thanks.
Lianbo
regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];
if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
--
2.25.1