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-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240201-exception_ip-v1-1-aa26ab3ee0b5@flygoat.com>
Date: Thu, 01 Feb 2024 15:46:27 +0000
From: Jiaxun Yang <jiaxun.yang@...goat.com>
To: Oleg Nesterov <oleg@...hat.com>, 
 Thomas Bogendoerfer <tsbogend@...ha.franken.de>, 
 Andrew Morton <akpm@...ux-foundation.org>, 
 Ben Hutchings <ben@...adent.org.uk>
Cc: linux-arch@...r.kernel.org, linux-kernel@...r.kernel.org, 
 linux-mips@...r.kernel.org, linux-mm@...ck.org, 
 Jiaxun Yang <jiaxun.yang@...goat.com>
Subject: [PATCH 1/3] ptrace: Introduce exception_ip arch hook

On architectures with delay slot, architecture level instruction
pointer (or program counter) in pt_regs may differ from where
exception was triggered.

Introduce exception_ip hook to invoke architecture code and determine
actual instruction pointer to the exception.

Link: https://lore.kernel.org/lkml/00d1b813-c55f-4365-8d81-d70258e10b16@app.fastmail.com/
Signed-off-by: Jiaxun Yang <jiaxun.yang@...goat.com>
---
 arch/alpha/include/asm/ptrace.h        | 1 +
 arch/arc/include/asm/ptrace.h          | 1 +
 arch/arm/include/asm/ptrace.h          | 1 +
 arch/csky/include/asm/ptrace.h         | 1 +
 arch/hexagon/include/uapi/asm/ptrace.h | 1 +
 arch/loongarch/include/asm/ptrace.h    | 1 +
 arch/m68k/include/asm/ptrace.h         | 1 +
 arch/microblaze/include/asm/ptrace.h   | 3 ++-
 arch/mips/include/asm/ptrace.h         | 1 +
 arch/mips/kernel/ptrace.c              | 7 +++++++
 arch/nios2/include/asm/ptrace.h        | 3 ++-
 arch/openrisc/include/asm/ptrace.h     | 1 +
 arch/parisc/include/asm/ptrace.h       | 1 +
 arch/s390/include/asm/ptrace.h         | 1 +
 arch/sparc/include/asm/ptrace.h        | 2 ++
 arch/um/include/asm/ptrace-generic.h   | 1 +
 16 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h
index 3557ce64ed21..1ded3f2d09e9 100644
--- a/arch/alpha/include/asm/ptrace.h
+++ b/arch/alpha/include/asm/ptrace.h
@@ -8,6 +8,7 @@
 #define arch_has_single_step()		(1)
 #define user_mode(regs) (((regs)->ps & 8) != 0)
 #define instruction_pointer(regs) ((regs)->pc)
+#define exception_ip(regs) instruction_pointer(regs)
 #define profile_pc(regs) instruction_pointer(regs)
 #define current_user_stack_pointer() rdusp()
 
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h
index 00b9318e551e..94084f1048df 100644
--- a/arch/arc/include/asm/ptrace.h
+++ b/arch/arc/include/asm/ptrace.h
@@ -105,6 +105,7 @@ struct callee_regs {
 #endif
 
 #define instruction_pointer(regs)	((regs)->ret)
+#define exception_ip(regs)		instruction_pointer(regs)
 #define profile_pc(regs)		instruction_pointer(regs)
 
 /* return 1 if user mode or 0 if kernel mode */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 7f44e88d1f25..fb4dc23eba78 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -89,6 +89,7 @@ static inline long regs_return_value(struct pt_regs *regs)
 }
 
 #define instruction_pointer(regs)	(regs)->ARM_pc
+#define exception_ip(regs)			instruction_pointer(regs)
 
 #ifdef CONFIG_THUMB2_KERNEL
 #define frame_pointer(regs) (regs)->ARM_r7
diff --git a/arch/csky/include/asm/ptrace.h b/arch/csky/include/asm/ptrace.h
index 0634b7895d81..a738630e64b0 100644
--- a/arch/csky/include/asm/ptrace.h
+++ b/arch/csky/include/asm/ptrace.h
@@ -22,6 +22,7 @@
 
 #define user_mode(regs) (!((regs)->sr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
+#define exception_ip(regs) instruction_pointer(regs)
 #define profile_pc(regs) instruction_pointer(regs)
 #define trap_no(regs) ((regs->sr >> 16) & 0xff)
 
diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h
index 2a3ea14ad9b9..846471936237 100644
--- a/arch/hexagon/include/uapi/asm/ptrace.h
+++ b/arch/hexagon/include/uapi/asm/ptrace.h
@@ -25,6 +25,7 @@
 #include <asm/registers.h>
 
 #define instruction_pointer(regs) pt_elr(regs)
+#define exception_ip(regs) instruction_pointer(regs)
 #define user_stack_pointer(regs) ((regs)->r29)
 
 #define profile_pc(regs) instruction_pointer(regs)
diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h
index f3ddaed9ef7f..a34327f0e69d 100644
--- a/arch/loongarch/include/asm/ptrace.h
+++ b/arch/loongarch/include/asm/ptrace.h
@@ -160,6 +160,7 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long val
 }
 
 #define instruction_pointer(regs) ((regs)->csr_era)
+#define exception_ip(regs) instruction_pointer(regs)
 #define profile_pc(regs) instruction_pointer(regs)
 
 extern void die(const char *str, struct pt_regs *regs);
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index ea5a80ca1ab3..cb553e2ec73a 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -13,6 +13,7 @@
 
 #define user_mode(regs) (!((regs)->sr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
+#define exception_ip(regs) instruction_pointer(regs)
 #define profile_pc(regs) instruction_pointer(regs)
 #define current_pt_regs() \
 	(struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h
index bfcb89df5e26..974c00fa7212 100644
--- a/arch/microblaze/include/asm/ptrace.h
+++ b/arch/microblaze/include/asm/ptrace.h
@@ -12,7 +12,8 @@
 #define user_mode(regs)			(!kernel_mode(regs))
 
 #define instruction_pointer(regs)	((regs)->pc)
-#define profile_pc(regs)		instruction_pointer(regs)
+#define exception_ip(regs)			instruction_pointer(regs)
+#define profile_pc(regs)			instruction_pointer(regs)
 #define user_stack_pointer(regs)	((regs)->r1)
 
 static inline long regs_return_value(struct pt_regs *regs)
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index daf3cf244ea9..97589731fd40 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -154,6 +154,7 @@ static inline long regs_return_value(struct pt_regs *regs)
 }
 
 #define instruction_pointer(regs) ((regs)->cp0_epc)
+extern unsigned long exception_ip(struct pt_regs *regs);
 #define profile_pc(regs) instruction_pointer(regs)
 
 extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index d9df543f7e2c..59288c13b581 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -31,6 +31,7 @@
 #include <linux/seccomp.h>
 #include <linux/ftrace.h>
 
+#include <asm/branch.h>
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-info.h>
@@ -48,6 +49,12 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/syscalls.h>
 
+unsigned long exception_ip(struct pt_regs *regs)
+{
+	return exception_epc(regs);
+}
+EXPORT_SYMBOL(exception_ip);
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
diff --git a/arch/nios2/include/asm/ptrace.h b/arch/nios2/include/asm/ptrace.h
index 9da34c3022a2..136f5679ae79 100644
--- a/arch/nios2/include/asm/ptrace.h
+++ b/arch/nios2/include/asm/ptrace.h
@@ -66,7 +66,8 @@ struct switch_stack {
 #define user_mode(regs)	(((regs)->estatus & ESTATUS_EU))
 
 #define instruction_pointer(regs)	((regs)->ra)
-#define profile_pc(regs)		instruction_pointer(regs)
+#define exception_ip(regs)			instruction_pointer(regs)
+#define profile_pc(regs)			instruction_pointer(regs)
 #define user_stack_pointer(regs)	((regs)->sp)
 extern void show_regs(struct pt_regs *);
 
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 375147ff71fc..67c28484d17e 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -67,6 +67,7 @@ struct pt_regs {
 #define STACK_FRAME_OVERHEAD  128  /* size of minimum stack frame */
 
 #define instruction_pointer(regs)	((regs)->pc)
+#define exception_ip(regs)			instruction_pointer(regs)
 #define user_mode(regs)			(((regs)->sr & SPR_SR_SM) == 0)
 #define user_stack_pointer(regs)	((unsigned long)(regs)->sp)
 #define profile_pc(regs)		instruction_pointer(regs)
diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h
index eea3f3df0823..d7e8dcf26582 100644
--- a/arch/parisc/include/asm/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -17,6 +17,7 @@
 #define user_mode(regs)			(((regs)->iaoq[0] & 3) != PRIV_KERNEL)
 #define user_space(regs)		((regs)->iasq[1] != PRIV_KERNEL)
 #define instruction_pointer(regs)	((regs)->iaoq[0] & ~3)
+#define exception_ip(regs)			instruction_pointer(regs)
 #define user_stack_pointer(regs)	((regs)->gr[30])
 unsigned long profile_pc(struct pt_regs *);
 
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index d28bf8fb2799..a5255b2337af 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -211,6 +211,7 @@ static inline int test_and_clear_pt_regs_flag(struct pt_regs *regs, int flag)
 
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr)
+#define exception_ip(regs) instruction_pointer(regs)
 #define user_stack_pointer(regs)((regs)->gprs[15])
 #define profile_pc(regs) instruction_pointer(regs)
 
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index d1419e669027..41ae186f2245 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -63,6 +63,7 @@ extern union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
 #define force_successful_syscall_return() set_thread_noerror(1)
 #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
 #define instruction_pointer(regs) ((regs)->tpc)
+#define exception_ip(regs) instruction_pointer(regs)
 #define instruction_pointer_set(regs, val) do { \
 		(regs)->tpc = (val); \
 		(regs)->tnpc = (val)+4; \
@@ -142,6 +143,7 @@ static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
 
 #define user_mode(regs) (!((regs)->psr & PSR_PS))
 #define instruction_pointer(regs) ((regs)->pc)
+#define exception_ip(regs) instruction_pointer(regs)
 #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
 unsigned long profile_pc(struct pt_regs *);
 #else /* (!__ASSEMBLY__) */
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index adf91ef553ae..f9ada287ca12 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -26,6 +26,7 @@ struct pt_regs {
 #define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
 
 #define instruction_pointer(regs) PT_REGS_IP(regs)
+#define exception_ip(regs) instruction_pointer(regs)
 
 #define PTRACE_OLDSETOPTIONS 21
 

-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ