Thread (21 messages) flat view 21 messages, 4 authors, 2020-09-18

Re: [PATCH v6 8/8] powerpc/watchpoint/selftests: Tests for kernel accessing user memory

From: Rogerio Alves <hidden>
Date: 2020-09-17 13:55:13
Also in: lkml


On 9/2/20 1:29 AM, Ravi Bangoria wrote:
Introduce tests to cover simple scenarios where user is watching
memory which can be accessed by kernel as well. We also support
_MODE_EXACT with _SETHWDEBUG interface. Move those testcases out-
side of _BP_RANGE condition. This will help to test _MODE_EXACT
scenarios when CONFIG_HAVE_HW_BREAKPOINT is not set, eg:

   $ ./ptrace-hwbreak
   ...
   PTRACE_SET_DEBUGREG, Kernel Access Userspace, len: 8: Ok
   PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok
   PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok
   PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok
   PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace, len: 1: Ok
   success: ptrace-hwbreak

Suggested-by: Pedro Miraglia Franco de Carvalho <redacted>
Signed-off-by: Ravi Bangoria <redacted>
Tested-by: Rogerio Alves <redacted>
quoted hunk ↗ jump to hunk
---
  .../selftests/powerpc/ptrace/ptrace-hwbreak.c | 48 ++++++++++++++++++-
  1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
index fc477dfe86a2..2e0d86e0687e 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
@@ -20,6 +20,8 @@
  #include <signal.h>
  #include <sys/types.h>
  #include <sys/wait.h>
+#include <sys/syscall.h>
+#include <linux/limits.h>
  #include "ptrace.h"
  
  #define SPRN_PVR	0x11F
@@ -44,6 +46,7 @@ struct gstruct {
  };
  static volatile struct gstruct gstruct __attribute__((aligned(512)));
  
+static volatile char cwd[PATH_MAX] __attribute__((aligned(8)));
  
  static void get_dbginfo(pid_t child_pid, struct ppc_debug_info *dbginfo)
  {
@@ -138,6 +141,9 @@ static void test_workload(void)
  			write_var(len);
  	}
  
+	/* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
+	syscall(__NR_getcwd, &cwd, PATH_MAX);
+
  	/* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */
  	write_var(1);
  
@@ -150,6 +156,9 @@ static void test_workload(void)
  	else
  		read_var(1);
  
+	/* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
+	syscall(__NR_getcwd, &cwd, PATH_MAX);
+
  	/* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */
  	gstruct.a[rand() % A_LEN] = 'a';
  
@@ -293,6 +302,24 @@ static int test_set_debugreg(pid_t child_pid)
  	return 0;
  }
  
+static int test_set_debugreg_kernel_userspace(pid_t child_pid)
+{
+	unsigned long wp_addr = (unsigned long)cwd;
+	char *name = "PTRACE_SET_DEBUGREG";
+
+	/* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
+	wp_addr &= ~0x7UL;
+	wp_addr |= (1Ul << DABR_READ_SHIFT);
+	wp_addr |= (1UL << DABR_WRITE_SHIFT);
+	wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
+	ptrace_set_debugreg(child_pid, wp_addr);
+	ptrace(PTRACE_CONT, child_pid, NULL, 0);
+	check_success(child_pid, name, "Kernel Access Userspace", wp_addr, 8);
+
+	ptrace_set_debugreg(child_pid, 0);
+	return 0;
+}
+
  static void get_ppc_hw_breakpoint(struct ppc_hw_breakpoint *info, int type,
  				  unsigned long addr, int len)
  {
@@ -338,6 +365,22 @@ static void test_sethwdebug_exact(pid_t child_pid)
  	ptrace_delhwdebug(child_pid, wh);
  }
  
+static void test_sethwdebug_exact_kernel_userspace(pid_t child_pid)
+{
+	struct ppc_hw_breakpoint info;
+	unsigned long wp_addr = (unsigned long)&cwd;
+	char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT";
+	int len = 1; /* hardcoded in kernel */
+	int wh;
+
+	/* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
+	get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0);
+	wh = ptrace_sethwdebug(child_pid, &info);
+	ptrace(PTRACE_CONT, child_pid, NULL, 0);
+	check_success(child_pid, name, "Kernel Access Userspace", wp_addr, len);
+	ptrace_delhwdebug(child_pid, wh);
+}
+
  static void test_sethwdebug_range_aligned(pid_t child_pid)
  {
  	struct ppc_hw_breakpoint info;
@@ -452,9 +495,10 @@ static void
  run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr)
  {
  	test_set_debugreg(child_pid);
+	test_set_debugreg_kernel_userspace(child_pid);
+	test_sethwdebug_exact(child_pid);
+	test_sethwdebug_exact_kernel_userspace(child_pid);
  	if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) {
-		test_sethwdebug_exact(child_pid);
-
  		test_sethwdebug_range_aligned(child_pid);
  		if (dawr || is_8xx) {
  			test_sethwdebug_range_unaligned(child_pid);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help