lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 19 Apr 2022 10:34:16 +0300
From:   Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>
To:     linux-kernel@...r.kernel.org
Cc:     x86@...nel.org, mingo@...hat.com, jpoimboe@...hat.com,
        Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>
Subject: [PATCH v3] x86/unwind/orc: Recheck address range after stack info was updated

Otherwise crash is possible in case of other bug in IBS handling code which
is passing invalid regs to the unwinder.

Original OOPS log:
BUG: stack guard page was hit at 000000000dd984a2 (stack is 00000000d1caafca..00000000613712f0)
kernel stack overflow (page fault): 0000 [#1] SMP NOPTI
CPU: 93 PID: 23787 Comm: context_switch1 Not tainted 5.4.145 #1
RIP: 0010:unwind_next_frame
Call Trace:
 <NMI>
 perf_callchain_kernel
 get_perf_callchain
 perf_callchain
 perf_prepare_sample
 perf_event_output_forward
 __perf_event_overflow
 perf_ibs_handle_irq
 perf_ibs_nmi_handler
 nmi_handle
 default_do_nmi
 do_nmi
 end_repeat_nmi

Signed-off-by: Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>
---

Changelog:
 v1->v2: Do not call on_stack() twice for valid range
 v2->v3: Update commit message accrording to Josh's comments

 arch/x86/kernel/unwind_orc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
index 794fdef2501a..38185aedf7d1 100644
--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -339,11 +339,11 @@ static bool stack_access_ok(struct unwind_state *state, unsigned long _addr,
 	struct stack_info *info = &state->stack_info;
 	void *addr = (void *)_addr;
 
-	if (!on_stack(info, addr, len) &&
-	    (get_stack_info(addr, state->task, info, &state->stack_mask)))
-		return false;
+	if (on_stack(info, addr, len))
+		return true;
 
-	return true;
+	return !get_stack_info(addr, state->task, info, &state->stack_mask) &&
+		on_stack(info, addr, len);
 }
 
 static bool deref_stack_reg(struct unwind_state *state, unsigned long addr,
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ