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>] [day] [month] [year] [list]
Date:	Tue, 23 Dec 2014 16:42:06 -0800
From:	Doug Anderson <dianders@...omium.org>
To:	linux@....linux.org.uk, Jason Wessel <jason.wessel@...driver.com>
Cc:	Kevin Hilman <khilman@...aro.org>, osandov@...ndov.com,
	Dmitry Torokhov <dmitry.torokhov@...il.com>,
	Sonny Rao <sonnyrao@...omium.org>,
	Doug Anderson <dianders@...omium.org>, nico@...aro.org,
	will.deacon@....com, linux-arm-kernel@...ts.infradead.org,
	linux-kernel@...r.kernel.org
Subject: [RFC PATCH] arm: kgdb: Fix registers on sleeping tasks

Dumping registers from other sleeping tasks in KGDB was totally
failing for me.  All registers were reported as 0.

It looks as if the code was looking at at "task_pt_regs(task)" for the
sleeping task and they were all 0.  I'm not exactly sure why this
structure was used and why it wasn't filled in.

There is a more reliable place to look for all of the important
registers for a sleeping task: the task_thread_info.  This is the same
place that is referred to when doing a dump of all sleeping task
stacks (kdb_show_stack() -> show_stack() -> dump_backtrace() ->
unwind_backtrace() -> thread_saved_sp()).

Let's use the more reliable place for all registers that are saved
there.  We'll fall back to the task_pt_regs() for registers that we
don't have.

Signed-off-by: Doug Anderson <dianders@...omium.org>
---
 arch/arm/kernel/kgdb.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 07db2f8..bab69db 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -75,6 +75,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
 void
 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 {
+	struct thread_info *ti;
 	struct pt_regs *thread_regs;
 	int regno;
 
@@ -86,24 +87,34 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 	for (regno = 0; regno < GDB_MAX_REGS; regno++)
 		gdb_regs[regno] = 0;
 
-	/* Otherwise, we have only some registers from switch_to() */
+	/*
+	 * Try to get as much as we can from the thread_info since the
+	 * pt_regs structure doesn't seem right in most cases.
+	 */
+	ti			= task_thread_info(task);
+	gdb_regs[_R4]		= ti->cpu_context.r4;
+	gdb_regs[_R5]		= ti->cpu_context.r5;
+	gdb_regs[_R6]		= ti->cpu_context.r6;
+	gdb_regs[_R7]		= ti->cpu_context.r7;
+	gdb_regs[_R8]		= ti->cpu_context.r8;
+	gdb_regs[_R9]		= ti->cpu_context.r9;
+	gdb_regs[_R10]		= ti->cpu_context.sl;
+	gdb_regs[_FP]		= ti->cpu_context.fp;
+	gdb_regs[_SPT]		= ti->cpu_context.sp;
+	gdb_regs[_PC]		= ti->cpu_context.pc;
+
+	/*
+	 * task_thread_info() doesn't store callee-saved registers so we'll
+	 * give task_pt_regs() a shot here.  I've never actually seen that be
+	 * valid, though
+	 */
 	thread_regs		= task_pt_regs(task);
 	gdb_regs[_R0]		= thread_regs->ARM_r0;
 	gdb_regs[_R1]		= thread_regs->ARM_r1;
 	gdb_regs[_R2]		= thread_regs->ARM_r2;
 	gdb_regs[_R3]		= thread_regs->ARM_r3;
-	gdb_regs[_R4]		= thread_regs->ARM_r4;
-	gdb_regs[_R5]		= thread_regs->ARM_r5;
-	gdb_regs[_R6]		= thread_regs->ARM_r6;
-	gdb_regs[_R7]		= thread_regs->ARM_r7;
-	gdb_regs[_R8]		= thread_regs->ARM_r8;
-	gdb_regs[_R9]		= thread_regs->ARM_r9;
-	gdb_regs[_R10]		= thread_regs->ARM_r10;
-	gdb_regs[_FP]		= thread_regs->ARM_fp;
 	gdb_regs[_IP]		= thread_regs->ARM_ip;
-	gdb_regs[_SPT]		= thread_regs->ARM_sp;
 	gdb_regs[_LR]		= thread_regs->ARM_lr;
-	gdb_regs[_PC]		= thread_regs->ARM_pc;
 	gdb_regs[_CPSR]		= thread_regs->ARM_cpsr;
 }
 
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ