Skip to content

Commit

Permalink
Fix segfault in arm64_is_kernel_exception_frame() when corrupt stack …
Browse files Browse the repository at this point in the history
…pointer address is given

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@fujitsu.com>
  • Loading branch information
d-hatayama authored and k-hagio committed Jun 1, 2023
1 parent db8c030 commit 9868ebc
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))])))
Expand Down

0 comments on commit 9868ebc

Please sign in to comment.