* [PATCH v3] powerpc: Implement arch_within_stack_frames
@ 2023-02-28 5:43 Nicholas Miehlbradt
2023-04-06 1:09 ` Michael Ellerman
0 siblings, 1 reply; 2+ messages in thread
From: Nicholas Miehlbradt @ 2023-02-28 5:43 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Miehlbradt, ruscur
Walks the stack when copy_{to,from}_user address is in the stack to
ensure that the object being copied is entirely a single stack frame and
does not contain stack metadata.
Substantially similar to the x86 implementation. The back chain is used
to traverse the stack and identify stack frame boundaries.
Signed-off-by: Nicholas Miehlbradt <nicholas@linux.ibm.com>
---
v3: Move STACK_FRAME_PARAMS macros to ppc_asm.h
Add diagram in comments to show position of pointers into the stack during execution
v2: Rename PARAMETER_SAVE_OFFSET to STACK_FRAME_PARAMS
Add definitions of STACK_FRAME_PARAMS for PPC32 and remove dependancy on PPC64
Ignore the current stack frame and start with it's parent, similar to x86
v1: https://lore.kernel.org/linuxppc-dev/20221214044252.1910657-1-nicholas@linux.ibm.com/
v2: https://lore.kernel.org/linuxppc-dev/20230119053127.17782-1-nicholas@linux.ibm.com/
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/ppc_asm.h | 8 ++++++
arch/powerpc/include/asm/thread_info.h | 38 ++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2c9cdf1d8761..3ce17f9aa90a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -200,6 +200,7 @@ config PPC
select HAVE_ARCH_KCSAN if PPC_BOOK3S_64
select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
+ select HAVE_ARCH_WITHIN_STACK_FRAMES
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index d2f44612f4b0..1f1a64b780e3 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -837,4 +837,12 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
#define BTB_FLUSH(reg)
#endif /* CONFIG_PPC_E500 */
+#if defined(CONFIG_PPC64_ELF_ABI_V1)
+#define STACK_FRAME_PARAMS 48
+#elif defined(CONFIG_PPC64_ELF_ABI_V2)
+#define STACK_FRAME_PARAMS 32
+#elif defined(CONFIG_PPC32)
+#define STACK_FRAME_PARAMS 8
+#endif
+
#endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index af58f1ed3952..07f1901da8fd 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -45,6 +45,7 @@
#include <linux/cache.h>
#include <asm/processor.h>
#include <asm/accounting.h>
+#include <asm/ppc_asm.h>
#define SLB_PRELOAD_NR 16U
/*
@@ -186,6 +187,43 @@ static inline bool test_thread_local_flags(unsigned int flags)
#define is_elf2_task() (0)
#endif
+/*
+ * Walks up the stack frames to make sure that the specified object is
+ * entirely contained by a single stack frame.
+ *
+ * Returns:
+ * GOOD_FRAME if within a frame
+ * BAD_STACK if placed across a frame boundary (or outside stack)
+ */
+static inline int arch_within_stack_frames(const void * const stack,
+ const void * const stackend,
+ const void *obj, unsigned long len)
+{
+ const void *params;
+ const void *frame;
+
+ params = *(const void * const *)current_stack_pointer + STACK_FRAME_PARAMS;
+ frame = **(const void * const * const *)current_stack_pointer;
+
+ /*
+ * low -----------------------------------------------------------> high
+ * [backchain][metadata][params][local vars][saved registers][backchain]
+ * ^------------------------------------^
+ * | allows copies only in this region |
+ * | |
+ * params frame
+ * The metadata region contains the saved LR, CR etc.
+ */
+ while (stack <= frame && frame < stackend) {
+ if (obj + len <= frame)
+ return obj >= params ? GOOD_FRAME : BAD_STACK;
+ params = frame + STACK_FRAME_PARAMS;
+ frame = *(const void * const *)frame;
+ }
+
+ return BAD_STACK;
+}
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] powerpc: Implement arch_within_stack_frames
2023-02-28 5:43 [PATCH v3] powerpc: Implement arch_within_stack_frames Nicholas Miehlbradt
@ 2023-04-06 1:09 ` Michael Ellerman
0 siblings, 0 replies; 2+ messages in thread
From: Michael Ellerman @ 2023-04-06 1:09 UTC (permalink / raw)
To: linuxppc-dev, Nicholas Miehlbradt; +Cc: ruscur
On Tue, 28 Feb 2023 05:43:55 +0000, Nicholas Miehlbradt wrote:
> Walks the stack when copy_{to,from}_user address is in the stack to
> ensure that the object being copied is entirely a single stack frame and
> does not contain stack metadata.
>
> Substantially similar to the x86 implementation. The back chain is used
> to traverse the stack and identify stack frame boundaries.
>
> [...]
Applied to powerpc/next.
[1/1] powerpc: Implement arch_within_stack_frames
https://git.kernel.org/powerpc/c/ac9c8901cb10aab043bf3599d19eebacfcda2858
cheers
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-04-06 1:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-28 5:43 [PATCH v3] powerpc: Implement arch_within_stack_frames Nicholas Miehlbradt
2023-04-06 1:09 ` Michael Ellerman
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).