linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc: Interrupt handler stack randomisation
@ 2022-10-25  3:38 Rohan McLure
  2022-11-03  7:52 ` Christophe Leroy
  2022-11-07 11:55 ` Nicholas Piggin
  0 siblings, 2 replies; 3+ messages in thread
From: Rohan McLure @ 2022-10-25  3:38 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Rohan McLure

Stack frames used by syscall handlers support random offsets as of
commit f4a0318f278d (powerpc: add support for syscall stack randomization).
Implement the same for general interrupt handlers, by applying the
random stack offset and then updating this offset from within the
DEFINE_INTERRUPT_HANDLER macros.

Applying this offset perturbs the layout of interrupt handler stack
frames, rendering to the kernel stack more difficult to control by means
of user invoked interrupts.

Link: https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-May/243238.html

Signed-off-by: Rohan McLure <rmclure@linux.ibm.com>
---
 arch/powerpc/include/asm/interrupt.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index 4745bb9998bd..b7f7beff4e13 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -68,6 +68,7 @@
 
 #include <linux/context_tracking.h>
 #include <linux/hardirq.h>
+#include <linux/randomize_kstack.h>
 #include <asm/cputime.h>
 #include <asm/firmware.h>
 #include <asm/ftrace.h>
@@ -448,9 +449,12 @@ interrupt_handler long func(struct pt_regs *regs)			\
 	long ret;							\
 									\
 	__hard_RI_enable();						\
+	add_random_kstack_offset();					\
 									\
 	ret = ____##func (regs);					\
 									\
+	choose_random_kstack_offset(mftb());				\
+									\
 	return ret;							\
 }									\
 NOKPROBE_SYMBOL(func);							\
@@ -480,9 +484,11 @@ static __always_inline void ____##func(struct pt_regs *regs);		\
 interrupt_handler void func(struct pt_regs *regs)			\
 {									\
 	interrupt_enter_prepare(regs);					\
+	add_random_kstack_offset();					\
 									\
 	____##func (regs);						\
 									\
+	choose_random_kstack_offset(mftb());				\
 	interrupt_exit_prepare(regs);					\
 }									\
 NOKPROBE_SYMBOL(func);							\
@@ -515,9 +521,11 @@ interrupt_handler long func(struct pt_regs *regs)			\
 	long ret;							\
 									\
 	interrupt_enter_prepare(regs);					\
+	add_random_kstack_offset();					\
 									\
 	ret = ____##func (regs);					\
 									\
+	choose_random_kstack_offset(mftb());				\
 	interrupt_exit_prepare(regs);					\
 									\
 	return ret;							\
@@ -548,9 +556,11 @@ static __always_inline void ____##func(struct pt_regs *regs);		\
 interrupt_handler void func(struct pt_regs *regs)			\
 {									\
 	interrupt_async_enter_prepare(regs);				\
+	add_random_kstack_offset();					\
 									\
 	____##func (regs);						\
 									\
+	choose_random_kstack_offset(mftb());				\
 	interrupt_async_exit_prepare(regs);				\
 }									\
 NOKPROBE_SYMBOL(func);							\
@@ -585,9 +595,11 @@ interrupt_handler long func(struct pt_regs *regs)			\
 	long ret;							\
 									\
 	interrupt_nmi_enter_prepare(regs, &state);			\
+	add_random_kstack_offset();					\
 									\
 	ret = ____##func (regs);					\
 									\
+	choose_random_kstack_offset(mftb());				\
 	interrupt_nmi_exit_prepare(regs, &state);			\
 									\
 	return ret;							\
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] powerpc: Interrupt handler stack randomisation
  2022-10-25  3:38 [PATCH] powerpc: Interrupt handler stack randomisation Rohan McLure
@ 2022-11-03  7:52 ` Christophe Leroy
  2022-11-07 11:55 ` Nicholas Piggin
  1 sibling, 0 replies; 3+ messages in thread
From: Christophe Leroy @ 2022-11-03  7:52 UTC (permalink / raw)
  To: Rohan McLure, linuxppc-dev@lists.ozlabs.org



Le 25/10/2022 à 05:38, Rohan McLure a écrit :
> Stack frames used by syscall handlers support random offsets as of
> commit f4a0318f278d (powerpc: add support for syscall stack randomization).
> Implement the same for general interrupt handlers, by applying the
> random stack offset and then updating this offset from within the
> DEFINE_INTERRUPT_HANDLER macros.
> 
> Applying this offset perturbs the layout of interrupt handler stack
> frames, rendering to the kernel stack more difficult to control by means
> of user invoked interrupts.
> 
> Link: https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-May/243238.html
> 
> Signed-off-by: Rohan McLure <rmclure@linux.ibm.com>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>


> ---
>   arch/powerpc/include/asm/interrupt.h | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
> index 4745bb9998bd..b7f7beff4e13 100644
> --- a/arch/powerpc/include/asm/interrupt.h
> +++ b/arch/powerpc/include/asm/interrupt.h
> @@ -68,6 +68,7 @@
>   
>   #include <linux/context_tracking.h>
>   #include <linux/hardirq.h>
> +#include <linux/randomize_kstack.h>
>   #include <asm/cputime.h>
>   #include <asm/firmware.h>
>   #include <asm/ftrace.h>
> @@ -448,9 +449,12 @@ interrupt_handler long func(struct pt_regs *regs)			\
>   	long ret;							\
>   									\
>   	__hard_RI_enable();						\
> +	add_random_kstack_offset();					\
>   									\
>   	ret = ____##func (regs);					\
>   									\
> +	choose_random_kstack_offset(mftb());				\
> +									\
>   	return ret;							\
>   }									\
>   NOKPROBE_SYMBOL(func);							\
> @@ -480,9 +484,11 @@ static __always_inline void ____##func(struct pt_regs *regs);		\
>   interrupt_handler void func(struct pt_regs *regs)			\
>   {									\
>   	interrupt_enter_prepare(regs);					\
> +	add_random_kstack_offset();					\
>   									\
>   	____##func (regs);						\
>   									\
> +	choose_random_kstack_offset(mftb());				\
>   	interrupt_exit_prepare(regs);					\
>   }									\
>   NOKPROBE_SYMBOL(func);							\
> @@ -515,9 +521,11 @@ interrupt_handler long func(struct pt_regs *regs)			\
>   	long ret;							\
>   									\
>   	interrupt_enter_prepare(regs);					\
> +	add_random_kstack_offset();					\
>   									\
>   	ret = ____##func (regs);					\
>   									\
> +	choose_random_kstack_offset(mftb());				\
>   	interrupt_exit_prepare(regs);					\
>   									\
>   	return ret;							\
> @@ -548,9 +556,11 @@ static __always_inline void ____##func(struct pt_regs *regs);		\
>   interrupt_handler void func(struct pt_regs *regs)			\
>   {									\
>   	interrupt_async_enter_prepare(regs);				\
> +	add_random_kstack_offset();					\
>   									\
>   	____##func (regs);						\
>   									\
> +	choose_random_kstack_offset(mftb());				\
>   	interrupt_async_exit_prepare(regs);				\
>   }									\
>   NOKPROBE_SYMBOL(func);							\
> @@ -585,9 +595,11 @@ interrupt_handler long func(struct pt_regs *regs)			\
>   	long ret;							\
>   									\
>   	interrupt_nmi_enter_prepare(regs, &state);			\
> +	add_random_kstack_offset();					\
>   									\
>   	ret = ____##func (regs);					\
>   									\
> +	choose_random_kstack_offset(mftb());				\
>   	interrupt_nmi_exit_prepare(regs, &state);			\
>   									\
>   	return ret;							\

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] powerpc: Interrupt handler stack randomisation
  2022-10-25  3:38 [PATCH] powerpc: Interrupt handler stack randomisation Rohan McLure
  2022-11-03  7:52 ` Christophe Leroy
@ 2022-11-07 11:55 ` Nicholas Piggin
  1 sibling, 0 replies; 3+ messages in thread
From: Nicholas Piggin @ 2022-11-07 11:55 UTC (permalink / raw)
  To: Rohan McLure, linuxppc-dev

On Tue Oct 25, 2022 at 1:38 PM AEST, Rohan McLure wrote:
> Stack frames used by syscall handlers support random offsets as of
> commit f4a0318f278d (powerpc: add support for syscall stack randomization).
> Implement the same for general interrupt handlers, by applying the
> random stack offset and then updating this offset from within the
> DEFINE_INTERRUPT_HANDLER macros.
>
> Applying this offset perturbs the layout of interrupt handler stack
> frames, rendering to the kernel stack more difficult to control by means
> of user invoked interrupts.

Can you randomise the irq/softirq stacks as well with a patch 2?

_Probably_ don't have to do another mftb for those AFAICS. Hard irq
should be driven by one of these handlers (including in the irq replay
case). Softirq fast path is driven from irq_exit() from the async
irq handlers, so that should be pretty well randomized. Softirq
slowpath is done by ksoftirqd using its own stack, so nothing to
be done there.

>
> Link: https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-May/243238.html
>
> Signed-off-by: Rohan McLure <rmclure@linux.ibm.com>
> ---
>  arch/powerpc/include/asm/interrupt.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
> index 4745bb9998bd..b7f7beff4e13 100644
> --- a/arch/powerpc/include/asm/interrupt.h
> +++ b/arch/powerpc/include/asm/interrupt.h
> @@ -68,6 +68,7 @@
>  
>  #include <linux/context_tracking.h>
>  #include <linux/hardirq.h>
> +#include <linux/randomize_kstack.h>
>  #include <asm/cputime.h>
>  #include <asm/firmware.h>
>  #include <asm/ftrace.h>
> @@ -448,9 +449,12 @@ interrupt_handler long func(struct pt_regs *regs)			\
>  	long ret;							\
>  									\
>  	__hard_RI_enable();						\
> +	add_random_kstack_offset();					\
>  									\
>  	ret = ____##func (regs);					\
>  									\
> +	choose_random_kstack_offset(mftb());				\
> +									\
>  	return ret;							\
>  }									\
>  NOKPROBE_SYMBOL(func);							\
> @@ -480,9 +484,11 @@ static __always_inline void ____##func(struct pt_regs *regs);		\
>  interrupt_handler void func(struct pt_regs *regs)			\
>  {									\
>  	interrupt_enter_prepare(regs);					\
> +	add_random_kstack_offset();					\
>  									\
>  	____##func (regs);						\
>  									\
> +	choose_random_kstack_offset(mftb());				\
>  	interrupt_exit_prepare(regs);					\
>  }									\
>  NOKPROBE_SYMBOL(func);							\

Hmm. It uses per-cpu data, so it actually can't be used for all
interrupt types, HMI and MCE because they're real-mode. SLB because
that might take an SLB fault, and maybe not hash faults either because
they might fault again I think?

You'd have to change the core code to let us put the offset in the paca.
Not sure if 32-bit has any such restrictions (e.g., does 32s need
MSR[RI] enabled before accessing per-cpu data?)

If you can do that that then I'd also put it as the first thing in
the func(), because the enter_prepare code can call non-trivial code
(e.g., irq_enter / nmi_enter).

Thnaks,
Nick


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-11-07 11:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-25  3:38 [PATCH] powerpc: Interrupt handler stack randomisation Rohan McLure
2022-11-03  7:52 ` Christophe Leroy
2022-11-07 11:55 ` Nicholas Piggin

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).