[PATCH v2 2/2] Fix segfault in arm64_is_kernel_exception_frame() when corrupt stack pointer address is given

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Due to the corrupted mapping fixed by the previous commit,
arm64_is_kernel_exception_frame() can receive invalid stack pointer
address via the 2nd argument; different NT_PRSTATUS contains different
task's stack pointer address. However, macro STACK_OFFSET_TYPE() never
checks if a given address is within the range of the kernel stack of
the corresponding task and hence can result in referring to outside of
bt->stackbuf.

	static int
	arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr)
	{
			struct arm64_pt_regs *regs;
		struct machine_specific *ms = machdep->machspec;

			regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))];

	=>	if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
			!(regs->pstate & (0xffffffff00000000ULL | PSR_MODE32_BIT)) &&
			is_kernel_text(regs->pc) &&
			is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELPACMASK)) {

To fix this issue, check if the given stack pointer address points to
the range of the kernel stack of the corresponding task, and abort if
it turns out to be invalid.

Although the corrupted mapping has already been fixed, this fix is
still needed because corrupt stack pointer address can still be passed
here from different reasons. Consider, for example, that data on the
kernel stack can be modified abnormally due to any kernel bugs or
hardware issues.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@xxxxxxxxxxx>
---
 defs.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/defs.h b/defs.h
index 655de55..a0fb3fb 100644
--- a/defs.h
+++ b/defs.h
@@ -976,7 +976,10 @@ struct bt_info {
 
 #define STACK_OFFSET_TYPE(OFF) \
   (((ulong)(OFF) > STACKSIZE()) ? \
-  (ulong)((ulong)(OFF) - (ulong)(bt->stackbase)) : (ulong)(OFF)) 
+  (((ulong)(OFF) < (ulong)(bt->stackbase) || (ulong)(OFF) >= (ulong)(bt->stackbase) + STACKSIZE()) ? \
+  error(FATAL, "invalid stack pointer is given\n") :			\
+   (ulong)((ulong)(OFF) - (ulong)(bt->stackbase))) :			\
+   (ulong)(OFF))
 
 #define GET_STACK_ULONG(OFF) \
  *((ulong *)((char *)(&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(OFF))])))
-- 
2.25.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux