@@ -57,6 +57,12 @@ static inline void ptrauth_keys_switch(struct ptrauth_keys *keys)
*/
#define ptrauth_pac_mask() GENMASK(54, VA_BITS)
+/* Only valid for EL0 TTBR0 instruction pointers */
+static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
+{
+ return ptr & ~ptrauth_pac_mask();
+}
+
#define mm_ctx_ptrauth_init(ctx) \
ptrauth_keys_init(&(ctx)->ptrauth_keys)
@@ -64,6 +70,7 @@ static inline void ptrauth_keys_switch(struct ptrauth_keys *keys)
ptrauth_keys_switch(&(ctx)->ptrauth_keys)
#else /* CONFIG_ARM64_PTR_AUTH */
+#define ptrauth_strip_insn_pac(lr) (lr)
#define mm_ctx_ptrauth_init(ctx)
#define mm_ctx_ptrauth_switch(ctx)
#endif /* CONFIG_ARM64_PTR_AUTH */
@@ -18,6 +18,7 @@
#include <linux/perf_event.h>
#include <linux/uaccess.h>
+#include <asm/pointer_auth.h>
#include <asm/stacktrace.h>
struct frame_tail {
@@ -35,6 +36,7 @@ user_backtrace(struct frame_tail __user *tail,
{
struct frame_tail buftail;
unsigned long err;
+ unsigned long lr;
/* Also check accessibility of one struct frame_tail beyond */
if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
@@ -47,7 +49,9 @@ user_backtrace(struct frame_tail __user *tail,
if (err)
return NULL;
- perf_callchain_store(entry, buftail.lr);
+ lr = ptrauth_strip_insn_pac(buftail.lr);
+
+ perf_callchain_store(entry, lr);
/*
* Frame pointers should strictly progress back up the stack