All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb@kernel.org>
To: linux-arm-kernel@lists.infradead.org
Cc: linux-hardening@vger.kernel.org, mark.rutland@arm.com,
	catalin.marinas@arm.com, will@kernel.org,
	Ard Biesheuvel <ardb@kernel.org>
Subject: [RFC PATCH 7/9] arm64: assembler: add unwind annotations to frame push/pop macros
Date: Wed, 13 Oct 2021 17:22:41 +0200	[thread overview]
Message-ID: <20211013152243.2216899-8-ardb@kernel.org> (raw)
In-Reply-To: <20211013152243.2216899-1-ardb@kernel.org>

In order to ensure that we can unwind from hand rolled assembly
routines, decorate the frame push/pop helper macros that are used by
non-leaf assembler routines with the appropriate annotations.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/include/asm/assembler.h | 26 +++++++++++++++++++-
 arch/arm64/include/asm/linkage.h   | 16 +++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ceed84ac4005..cebb6c8c489b 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -664,9 +664,10 @@ alternative_endif
 	 *              the new value of sp. Add @extra bytes of stack space
 	 *              for locals.
 	 */
-	.macro		frame_push, regcount:req, extra
+	.macro		frame_push, regcount:req, extra=0
 #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	paciasp
+	.cfi_negate_ra_state
 #endif
 	__frame		st, \regcount, \extra
 	.endm
@@ -681,14 +682,29 @@ alternative_endif
 	__frame		ld
 #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	autiasp
+	.cfi_negate_ra_state
 #endif
 	.endm
 
 	.macro		__frame_regs, reg1, reg2, op, num
 	.if		.Lframe_regcount == \num
 	\op\()r		\reg1, [sp, #(\num + 1) * 8]
+	.ifc		\op, st
+	.cfi_offset	\reg1, -.Lframe_cfa_offset
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 8
+	.else
+	.cfi_restore	\reg1
+	.endif
 	.elseif		.Lframe_regcount > \num
 	\op\()p		\reg1, \reg2, [sp, #(\num + 1) * 8]
+	.ifc		\op, st
+	.cfi_offset	\reg1, -.Lframe_cfa_offset
+	.cfi_offset	\reg2, -.Lframe_cfa_offset + 8
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 16
+	.else
+	.cfi_restore	\reg1
+	.cfi_restore	\reg2
+	.endif
 	.endif
 	.endm
 
@@ -708,7 +724,12 @@ alternative_endif
 	.set		.Lframe_regcount, \regcount
 	.set		.Lframe_extra, \extra
 	.set		.Lframe_local_offset, ((\regcount + 3) / 2) * 16
+	.set		.Lframe_cfa_offset, .Lframe_local_offset + .Lframe_extra
 	stp		x29, x30, [sp, #-.Lframe_local_offset - .Lframe_extra]!
+	.cfi_def_cfa_offset .Lframe_cfa_offset
+	.cfi_offset	x29, -.Lframe_cfa_offset
+	.cfi_offset	x30, -.Lframe_cfa_offset + 8
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 16
 	mov		x29, sp
 	.endif
 
@@ -723,6 +744,9 @@ alternative_endif
 	.error		"frame_push/frame_pop may not be nested"
 	.endif
 	ldp		x29, x30, [sp], #.Lframe_local_offset + .Lframe_extra
+	.cfi_restore	x29
+	.cfi_restore	x30
+	.cfi_def_cfa_offset 0
 	.set		.Lframe_regcount, -1
 	.endif
 	.endm
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..d984a6750b01 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -4,6 +4,9 @@
 #define __ALIGN		.align 2
 #define __ALIGN_STR	".align 2"
 
+#define SYM_FUNC_CFI_START	.cfi_startproc ;
+#define SYM_FUNC_CFI_END	.cfi_endproc ;
+
 #if defined(CONFIG_ARM64_BTI_KERNEL) && defined(__aarch64__)
 
 /*
@@ -12,6 +15,9 @@
  * instead.
  */
 #define BTI_C hint 34 ;
+#else
+#define BTI_C
+#endif
 
 /*
  * When using in-kernel BTI we need to ensure that PCS-conformant assembly
@@ -20,29 +26,37 @@
  */
 #define SYM_FUNC_START(name)				\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_NOALIGN(name)			\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_LOCAL(name)			\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_LOCAL_NOALIGN(name)		\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_WEAK(name)			\
 	SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_WEAK_NOALIGN(name)		\
 	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)		\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
-#endif
+#define SYM_FUNC_END(name)				\
+	SYM_FUNC_CFI_END				\
+	SYM_END(name, SYM_T_FUNC)
 
 /*
  * Annotate a function as position independent, i.e., safe to be called before
-- 
2.30.2


WARNING: multiple messages have this Message-ID (diff)
From: Ard Biesheuvel <ardb@kernel.org>
To: linux-arm-kernel@lists.infradead.org
Cc: linux-hardening@vger.kernel.org, mark.rutland@arm.com,
	catalin.marinas@arm.com, will@kernel.org,
	Ard Biesheuvel <ardb@kernel.org>
Subject: [RFC PATCH 7/9] arm64: assembler: add unwind annotations to frame push/pop macros
Date: Wed, 13 Oct 2021 17:22:41 +0200	[thread overview]
Message-ID: <20211013152243.2216899-8-ardb@kernel.org> (raw)
In-Reply-To: <20211013152243.2216899-1-ardb@kernel.org>

In order to ensure that we can unwind from hand rolled assembly
routines, decorate the frame push/pop helper macros that are used by
non-leaf assembler routines with the appropriate annotations.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/include/asm/assembler.h | 26 +++++++++++++++++++-
 arch/arm64/include/asm/linkage.h   | 16 +++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ceed84ac4005..cebb6c8c489b 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -664,9 +664,10 @@ alternative_endif
 	 *              the new value of sp. Add @extra bytes of stack space
 	 *              for locals.
 	 */
-	.macro		frame_push, regcount:req, extra
+	.macro		frame_push, regcount:req, extra=0
 #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	paciasp
+	.cfi_negate_ra_state
 #endif
 	__frame		st, \regcount, \extra
 	.endm
@@ -681,14 +682,29 @@ alternative_endif
 	__frame		ld
 #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	autiasp
+	.cfi_negate_ra_state
 #endif
 	.endm
 
 	.macro		__frame_regs, reg1, reg2, op, num
 	.if		.Lframe_regcount == \num
 	\op\()r		\reg1, [sp, #(\num + 1) * 8]
+	.ifc		\op, st
+	.cfi_offset	\reg1, -.Lframe_cfa_offset
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 8
+	.else
+	.cfi_restore	\reg1
+	.endif
 	.elseif		.Lframe_regcount > \num
 	\op\()p		\reg1, \reg2, [sp, #(\num + 1) * 8]
+	.ifc		\op, st
+	.cfi_offset	\reg1, -.Lframe_cfa_offset
+	.cfi_offset	\reg2, -.Lframe_cfa_offset + 8
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 16
+	.else
+	.cfi_restore	\reg1
+	.cfi_restore	\reg2
+	.endif
 	.endif
 	.endm
 
@@ -708,7 +724,12 @@ alternative_endif
 	.set		.Lframe_regcount, \regcount
 	.set		.Lframe_extra, \extra
 	.set		.Lframe_local_offset, ((\regcount + 3) / 2) * 16
+	.set		.Lframe_cfa_offset, .Lframe_local_offset + .Lframe_extra
 	stp		x29, x30, [sp, #-.Lframe_local_offset - .Lframe_extra]!
+	.cfi_def_cfa_offset .Lframe_cfa_offset
+	.cfi_offset	x29, -.Lframe_cfa_offset
+	.cfi_offset	x30, -.Lframe_cfa_offset + 8
+	.set		.Lframe_cfa_offset, .Lframe_cfa_offset - 16
 	mov		x29, sp
 	.endif
 
@@ -723,6 +744,9 @@ alternative_endif
 	.error		"frame_push/frame_pop may not be nested"
 	.endif
 	ldp		x29, x30, [sp], #.Lframe_local_offset + .Lframe_extra
+	.cfi_restore	x29
+	.cfi_restore	x30
+	.cfi_def_cfa_offset 0
 	.set		.Lframe_regcount, -1
 	.endif
 	.endm
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..d984a6750b01 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -4,6 +4,9 @@
 #define __ALIGN		.align 2
 #define __ALIGN_STR	".align 2"
 
+#define SYM_FUNC_CFI_START	.cfi_startproc ;
+#define SYM_FUNC_CFI_END	.cfi_endproc ;
+
 #if defined(CONFIG_ARM64_BTI_KERNEL) && defined(__aarch64__)
 
 /*
@@ -12,6 +15,9 @@
  * instead.
  */
 #define BTI_C hint 34 ;
+#else
+#define BTI_C
+#endif
 
 /*
  * When using in-kernel BTI we need to ensure that PCS-conformant assembly
@@ -20,29 +26,37 @@
  */
 #define SYM_FUNC_START(name)				\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_NOALIGN(name)			\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_LOCAL(name)			\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_LOCAL_NOALIGN(name)		\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_WEAK(name)			\
 	SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN)	\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
 #define SYM_FUNC_START_WEAK_NOALIGN(name)		\
 	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)		\
+	SYM_FUNC_CFI_START				\
 	BTI_C
 
-#endif
+#define SYM_FUNC_END(name)				\
+	SYM_FUNC_CFI_END				\
+	SYM_END(name, SYM_T_FUNC)
 
 /*
  * Annotate a function as position independent, i.e., safe to be called before
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-10-13 15:23 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-13 15:22 [RFC PATCH 0/9] arm64: use unwind data on GCC for shadow call stack Ard Biesheuvel
2021-10-13 15:22 ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 1/9] arm64: assembler: enable PAC for non-leaf assembler routines Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 2/9] arm64: cache: use ALIAS version of linkage macros for local aliases Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 3/9] arm64: crypto: avoid overlapping linkage definitions for AES-CBC Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 4/9] arm64: aes-neonbs: move frame pop to end of function Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 5/9] arm64: chacha-neon: move frame pop forward Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 6/9] arm64: smccc: create proper stack frames for HVC/SMC calls Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:44   ` Mark Brown
2021-10-13 15:44     ` Mark Brown
2021-10-13 15:22 ` Ard Biesheuvel [this message]
2021-10-13 15:22   ` [RFC PATCH 7/9] arm64: assembler: add unwind annotations to frame push/pop macros Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 8/9] arm64: unwind: add asynchronous unwind tables to the kernel proper Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:22 ` [RFC PATCH 9/9] arm64: implement dynamic shadow call stack for GCC Ard Biesheuvel
2021-10-13 15:22   ` Ard Biesheuvel
2021-10-13 15:42   ` Mark Brown
2021-10-13 15:42     ` Mark Brown
2021-10-13 22:35   ` Dan Li
2021-10-13 22:35     ` Dan Li
2021-10-14  9:41     ` Ard Biesheuvel
2021-10-14  9:41       ` Ard Biesheuvel
2021-10-13 17:52 ` [RFC PATCH 0/9] arm64: use unwind data on GCC for shadow call stack Ard Biesheuvel
2021-10-13 17:52   ` Ard Biesheuvel
2021-10-13 18:01 ` Nick Desaulniers
2021-10-13 18:01   ` Nick Desaulniers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211013152243.2216899-8-ardb@kernel.org \
    --to=ardb@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.