linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] MIPS: ptrace: protect watchpoint handling code from setting watchpoints
@ 2017-01-13  7:44 Marcin Nowakowski
  2017-01-13  7:44 ` Marcin Nowakowski
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Marcin Nowakowski @ 2017-01-13  7:44 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: James Hogan, linux-mips

With certain EVA configurations it is possible for the kernel address
space to overlap user address space, which allows the user to set
watchpoints on kernel addresses via ptrace.

If a watchpoint is set in the watch exception handling code (after
exception level has been cleared) then the system will hang in an
infinite loop when hitting a watchpoint while trying to process it.

To prevent that place all watch exception entry/exit code in a single
named section and disallow placing watchpoints in that area.

Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
 arch/mips/kernel/entry.S       |  2 +-
 arch/mips/kernel/genex.S       |  2 ++
 arch/mips/kernel/ptrace.c      | 14 ++++++++++++++
 arch/mips/kernel/traps.c       |  2 ++
 arch/mips/kernel/vmlinux.lds.S |  8 ++++++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 7791840..ef69a64 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -24,7 +24,7 @@
 #define __ret_from_irq	ret_from_exception
 #endif
 
-	.text
+	.section .text..no_watch
 	.align	5
 #ifndef CONFIG_PREEMPT
 FEXPORT(ret_from_exception)
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index dc0b296..102a9e8 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -433,6 +433,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 	BUILD_HANDLER ftlb ftlb none silent		/* #16 */
 	BUILD_HANDLER msa msa sti silent		/* #21 */
 	BUILD_HANDLER mdmx mdmx sti silent		/* #22 */
+.section .text..no_watch
 #ifdef	CONFIG_HARDWARE_WATCHPOINTS
 	/*
 	 * For watch, interrupts will be enabled after the watch
@@ -442,6 +443,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
 #else
 	BUILD_HANDLER watch watch sti verbose		/* #23 */
 #endif
+.previous
 	BUILD_HANDLER mcheck mcheck cli verbose		/* #24 */
 	BUILD_HANDLER mt mt sti silent			/* #25 */
 	BUILD_HANDLER dsp dsp sti silent		/* #26 */
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index c8ba260..1c8d75c 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -235,6 +235,17 @@ int ptrace_get_watch_regs(struct task_struct *child,
 	return 0;
 }
 
+static int ptrace_watch_in_watch_code_region(unsigned long addr)
+{
+	extern unsigned long __nowatch_text_start, __nowatch_text_end;
+	unsigned long start, end;
+
+	start = (((unsigned long)&__nowatch_text_start) & ~MIPS_WATCHLO_IRW);
+	end = (((unsigned long)&__nowatch_text_end) & ~MIPS_WATCHLO_IRW);
+
+	return addr >= start && addr < end;
+}
+
 int ptrace_set_watch_regs(struct task_struct *child,
 			  struct pt_watch_regs __user *addr)
 {
@@ -262,6 +273,9 @@ int ptrace_set_watch_regs(struct task_struct *child,
 				return -EINVAL;
 		}
 #endif
+		if (ptrace_watch_in_watch_code_region(lt[i]))
+			return -EINVAL;
+
 		__get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]);
 		if (ht[i] & ~MIPS_WATCHHI_MASK)
 			return -EINVAL;
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 6c7f9d7..b86ce85 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1509,6 +1509,8 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
  * Called with interrupts disabled.
  */
 asmlinkage void do_watch(struct pt_regs *regs)
+	__attribute__((section(".text..no_watch")));
+asmlinkage void do_watch(struct pt_regs *regs)
 {
 	siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT };
 	enum ctx_state prev_state;
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index d5de675..f76f481 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -32,6 +32,13 @@ PHDRS {
 	jiffies	 = jiffies_64;
 #endif
 
+#define NOWATCH_TEXT							\
+		ALIGN_FUNCTION();					\
+		VMLINUX_SYMBOL(__nowatch_text_start) = .;		\
+		*(.text..no_watch)					\
+		VMLINUX_SYMBOL(__nowatch_text_end) = .;
+
+
 SECTIONS
 {
 #ifdef CONFIG_BOOT_ELF64
@@ -54,6 +61,7 @@ SECTIONS
 	_text = .;	/* Text and read-only data */
 	.text : {
 		TEXT_TEXT
+		NOWATCH_TEXT
 		SCHED_TEXT
 		CPUIDLE_TEXT
 		LOCK_TEXT
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-01-23  9:06 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-13  7:44 [PATCH 1/2] MIPS: ptrace: protect watchpoint handling code from setting watchpoints Marcin Nowakowski
2017-01-13  7:44 ` Marcin Nowakowski
2017-01-13  7:44 ` [PATCH 2/2] MIPS: ptrace: disable watchpoints if hit in kernel mode Marcin Nowakowski
2017-01-13  7:44   ` Marcin Nowakowski
2017-01-13 11:42   ` James Hogan
2017-01-13 11:42     ` James Hogan
2017-01-23  9:06     ` Marcin Nowakowski
2017-01-23  9:06       ` Marcin Nowakowski
2017-01-13 11:11 ` [PATCH 1/2] MIPS: ptrace: protect watchpoint handling code from setting watchpoints James Hogan
2017-01-13 11:11   ` James Hogan
2017-01-13 11:33   ` Marcin Nowakowski
2017-01-13 11:33     ` Marcin Nowakowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).