linux-sh.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/2] cleanup stackprotector canary generation
@ 2022-10-23 20:32 Jason A. Donenfeld
  2022-10-23 20:32 ` [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h Jason A. Donenfeld
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-10-23 20:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jason A. Donenfeld, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Catalin Marinas, Chris Zankel, Christophe Leroy, Dave Hansen,
	Greg Kroah-Hartman, Guo Ren, H . Peter Anvin, Ingo Molnar,
	Juergen Gross, Max Filippov, Michael Ellerman, Nicholas Piggin,
	Palmer Dabbelt, Paul Walmsley, Rich Felker, Russell King,
	Thomas Bogendoerfer, Thomas Gleixner, Will Deacon,
	Yoshinori Sato, linux-arm-kernel, linux-csky, linux-mips,
	linux-riscv, linux-sh, linux-xtensa, linuxppc-dev, x86

Stack canary generation currently lives partially in random.h, where it
doesn't belong, and is in general a bit overcomplicated. This small
patchset fixes up both issues. I'll take these in my tree, unless
somebody else prefers to do so.

Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Rich Felker <dalias@libc.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-csky@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-sh@vger.kernel.org
Cc: linux-xtensa@linux-xtensa.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: x86@kernel.org

Jason A. Donenfeld (2):
  stackprotector: move CANARY_MASK and get_random_canary() into
    stackprotector.h
  stackprotector: actually use get_random_canary()

 arch/arm/include/asm/stackprotector.h     |  9 +--------
 arch/arm64/include/asm/stackprotector.h   |  9 +--------
 arch/csky/include/asm/stackprotector.h    | 10 +---------
 arch/mips/include/asm/stackprotector.h    |  9 +--------
 arch/powerpc/include/asm/stackprotector.h | 10 +---------
 arch/riscv/include/asm/stackprotector.h   | 10 +---------
 arch/sh/include/asm/stackprotector.h      | 10 +---------
 arch/x86/include/asm/stackprotector.h     | 14 +-------------
 arch/x86/kernel/cpu/common.c              |  2 +-
 arch/x86/kernel/setup_percpu.c            |  2 +-
 arch/x86/kernel/smpboot.c                 |  2 +-
 arch/x86/xen/enlighten_pv.c               |  2 +-
 arch/xtensa/include/asm/stackprotector.h  |  7 +------
 include/linux/random.h                    | 19 -------------------
 include/linux/stackprotector.h            | 19 +++++++++++++++++++
 kernel/fork.c                             |  2 +-
 16 files changed, 33 insertions(+), 103 deletions(-)

-- 
2.38.1


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

* [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h
  2022-10-23 20:32 [PATCH v1 0/2] cleanup stackprotector canary generation Jason A. Donenfeld
@ 2022-10-23 20:32 ` Jason A. Donenfeld
  2022-10-24  5:25   ` Philippe Mathieu-Daudé
  2022-10-23 20:32 ` [PATCH v1 2/2] stackprotector: actually use get_random_canary() Jason A. Donenfeld
  2022-10-24  5:03 ` [PATCH v1 0/2] cleanup stackprotector canary generation Greg Kroah-Hartman
  2 siblings, 1 reply; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-10-23 20:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jason A. Donenfeld, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Catalin Marinas, Chris Zankel, Christophe Leroy, Dave Hansen,
	Greg Kroah-Hartman, Guo Ren, H . Peter Anvin, Ingo Molnar,
	Juergen Gross, Max Filippov, Michael Ellerman, Nicholas Piggin,
	Palmer Dabbelt, Paul Walmsley, Rich Felker, Russell King,
	Thomas Bogendoerfer, Thomas Gleixner, Will Deacon,
	Yoshinori Sato, linux-arm-kernel, linux-csky, linux-mips,
	linux-riscv, linux-sh, linux-xtensa, linuxppc-dev, x86

This has nothing to do with random.c and everything to do with stack
protectors. Yes, it uses randomness. But many things use randomness.
random.h and random.c are concerned with the generation of randomness,
not with each and every use. So move this function into the more
specific stackprotector.h file where it belongs.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 arch/x86/kernel/cpu/common.c   |  2 +-
 arch/x86/kernel/setup_percpu.c |  2 +-
 arch/x86/kernel/smpboot.c      |  2 +-
 arch/x86/xen/enlighten_pv.c    |  2 +-
 include/linux/random.h         | 19 -------------------
 include/linux/stackprotector.h | 19 +++++++++++++++++++
 kernel/fork.c                  |  2 +-
 7 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 3e508f239098..3f66dd03c091 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -22,9 +22,9 @@
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
 #include <linux/pgtable.h>
+#include <linux/stackprotector.h>
 
 #include <asm/cmdline.h>
-#include <asm/stackprotector.h>
 #include <asm/perf_event.h>
 #include <asm/mmu_context.h>
 #include <asm/doublefault.h>
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 49325caa7307..b26123c90b4f 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 #include <linux/topology.h>
 #include <linux/pfn.h>
+#include <linux/stackprotector.h>
 #include <asm/sections.h>
 #include <asm/processor.h>
 #include <asm/desc.h>
@@ -21,7 +22,6 @@
 #include <asm/proto.h>
 #include <asm/cpumask.h>
 #include <asm/cpu.h>
-#include <asm/stackprotector.h>
 
 DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
 EXPORT_PER_CPU_SYMBOL(cpu_number);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f3ea0287f69..dbe09fcc6604 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -56,6 +56,7 @@
 #include <linux/numa.h>
 #include <linux/pgtable.h>
 #include <linux/overflow.h>
+#include <linux/stackprotector.h>
 
 #include <asm/acpi.h>
 #include <asm/desc.h>
@@ -80,7 +81,6 @@
 #include <asm/cpu_device_id.h>
 #include <asm/spec-ctrl.h>
 #include <asm/hw_irq.h>
-#include <asm/stackprotector.h>
 #include <asm/sev.h>
 
 /* representing HT siblings of each logical CPU */
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index f82857e48815..745420853a7c 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -32,6 +32,7 @@
 #include <linux/edd.h>
 #include <linux/reboot.h>
 #include <linux/virtio_anchor.h>
+#include <linux/stackprotector.h>
 
 #include <xen/xen.h>
 #include <xen/events.h>
@@ -64,7 +65,6 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
-#include <asm/stackprotector.h>
 #include <asm/hypervisor.h>
 #include <asm/mach_traps.h>
 #include <asm/mwait.h>
diff --git a/include/linux/random.h b/include/linux/random.h
index bf8ed3df3af0..182780cafd45 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -115,25 +115,6 @@ static inline u32 get_random_u32_between(u32 floor, u32 ceil)
 	return floor + get_random_u32_below(ceil - floor);
 }
 
-/*
- * On 64-bit architectures, protect against non-terminated C string overflows
- * by zeroing out the first byte of the canary; this leaves 56 bits of entropy.
- */
-#ifdef CONFIG_64BIT
-# ifdef __LITTLE_ENDIAN
-#  define CANARY_MASK 0xffffffffffffff00UL
-# else /* big endian, 64 bits: */
-#  define CANARY_MASK 0x00ffffffffffffffUL
-# endif
-#else /* 32 bits: */
-# define CANARY_MASK 0xffffffffUL
-#endif
-
-static inline unsigned long get_random_canary(void)
-{
-	return get_random_long() & CANARY_MASK;
-}
-
 void __init random_init_early(const char *command_line);
 void __init random_init(void);
 bool rng_is_initialized(void);
diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h
index 4c678c4fec58..9c88707d9a0f 100644
--- a/include/linux/stackprotector.h
+++ b/include/linux/stackprotector.h
@@ -6,6 +6,25 @@
 #include <linux/sched.h>
 #include <linux/random.h>
 
+/*
+ * On 64-bit architectures, protect against non-terminated C string overflows
+ * by zeroing out the first byte of the canary; this leaves 56 bits of entropy.
+ */
+#ifdef CONFIG_64BIT
+# ifdef __LITTLE_ENDIAN
+#  define CANARY_MASK 0xffffffffffffff00UL
+# else /* big endian, 64 bits: */
+#  define CANARY_MASK 0x00ffffffffffffffUL
+# endif
+#else /* 32 bits: */
+# define CANARY_MASK 0xffffffffUL
+#endif
+
+static inline unsigned long get_random_canary(void)
+{
+	return get_random_long() & CANARY_MASK;
+}
+
 #if defined(CONFIG_STACKPROTECTOR) || defined(CONFIG_ARM64_PTR_AUTH)
 # include <asm/stackprotector.h>
 #else
diff --git a/kernel/fork.c b/kernel/fork.c
index 08969f5aa38d..ec57cae58ff1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -75,7 +75,6 @@
 #include <linux/freezer.h>
 #include <linux/delayacct.h>
 #include <linux/taskstats_kern.h>
-#include <linux/random.h>
 #include <linux/tty.h>
 #include <linux/fs_struct.h>
 #include <linux/magic.h>
@@ -97,6 +96,7 @@
 #include <linux/scs.h>
 #include <linux/io_uring.h>
 #include <linux/bpf.h>
+#include <linux/stackprotector.h>
 
 #include <asm/pgalloc.h>
 #include <linux/uaccess.h>
-- 
2.38.1


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

* [PATCH v1 2/2] stackprotector: actually use get_random_canary()
  2022-10-23 20:32 [PATCH v1 0/2] cleanup stackprotector canary generation Jason A. Donenfeld
  2022-10-23 20:32 ` [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h Jason A. Donenfeld
@ 2022-10-23 20:32 ` Jason A. Donenfeld
  2022-10-24  0:47   ` Guo Ren
  2022-11-09 17:44   ` Catalin Marinas
  2022-10-24  5:03 ` [PATCH v1 0/2] cleanup stackprotector canary generation Greg Kroah-Hartman
  2 siblings, 2 replies; 7+ messages in thread
From: Jason A. Donenfeld @ 2022-10-23 20:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jason A. Donenfeld, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Catalin Marinas, Chris Zankel, Christophe Leroy, Dave Hansen,
	Greg Kroah-Hartman, Guo Ren, H . Peter Anvin, Ingo Molnar,
	Juergen Gross, Max Filippov, Michael Ellerman, Nicholas Piggin,
	Palmer Dabbelt, Paul Walmsley, Rich Felker, Russell King,
	Thomas Bogendoerfer, Thomas Gleixner, Will Deacon,
	Yoshinori Sato, linux-arm-kernel, linux-csky, linux-mips,
	linux-riscv, linux-sh, linux-xtensa, linuxppc-dev, x86

The RNG always mixes in the Linux version extremely early in boot. It
also always includes a cycle counter, not only during early boot, but
each and every time it is invoked prior to being fully initialized.
Together, this means that the use of additional xors inside of the
various stackprotector.h files is superfluous and over-complicated.
Instead, we can get exactly the same thing, but better, by just calling
`get_random_canary()`.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 arch/arm/include/asm/stackprotector.h     |  9 +--------
 arch/arm64/include/asm/stackprotector.h   |  9 +--------
 arch/csky/include/asm/stackprotector.h    | 10 +---------
 arch/mips/include/asm/stackprotector.h    |  9 +--------
 arch/powerpc/include/asm/stackprotector.h | 10 +---------
 arch/riscv/include/asm/stackprotector.h   | 10 +---------
 arch/sh/include/asm/stackprotector.h      | 10 +---------
 arch/x86/include/asm/stackprotector.h     | 14 +-------------
 arch/xtensa/include/asm/stackprotector.h  |  7 +------
 9 files changed, 9 insertions(+), 79 deletions(-)

diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
index 088d03161be5..0bd4979759f1 100644
--- a/arch/arm/include/asm/stackprotector.h
+++ b/arch/arm/include/asm/stackprotector.h
@@ -15,9 +15,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H 1
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 #include <asm/thread_info.h>
 
 extern unsigned long __stack_chk_guard;
@@ -30,11 +27,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 #ifndef CONFIG_STACKPROTECTOR_PER_TASK
diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h
index 33f1bb453150..ae3ad80f51fe 100644
--- a/arch/arm64/include/asm/stackprotector.h
+++ b/arch/arm64/include/asm/stackprotector.h
@@ -13,8 +13,6 @@
 #ifndef __ASM_STACKPROTECTOR_H
 #define __ASM_STACKPROTECTOR_H
 
-#include <linux/random.h>
-#include <linux/version.h>
 #include <asm/pointer_auth.h>
 
 extern unsigned long __stack_chk_guard;
@@ -28,12 +26,7 @@ extern unsigned long __stack_chk_guard;
 static __always_inline void boot_init_stack_canary(void)
 {
 #if defined(CONFIG_STACKPROTECTOR)
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
-	canary &= CANARY_MASK;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
diff --git a/arch/csky/include/asm/stackprotector.h b/arch/csky/include/asm/stackprotector.h
index d7cd4e51edd9..d23747447166 100644
--- a/arch/csky/include/asm/stackprotector.h
+++ b/arch/csky/include/asm/stackprotector.h
@@ -2,9 +2,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H 1
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 extern unsigned long __stack_chk_guard;
 
 /*
@@ -15,12 +12,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
-	canary &= CANARY_MASK;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	__stack_chk_guard = current->stack_canary;
diff --git a/arch/mips/include/asm/stackprotector.h b/arch/mips/include/asm/stackprotector.h
index 68d4be9e1254..518c192ad982 100644
--- a/arch/mips/include/asm/stackprotector.h
+++ b/arch/mips/include/asm/stackprotector.h
@@ -15,9 +15,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H 1
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 extern unsigned long __stack_chk_guard;
 
 /*
@@ -28,11 +25,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	__stack_chk_guard = current->stack_canary;
diff --git a/arch/powerpc/include/asm/stackprotector.h b/arch/powerpc/include/asm/stackprotector.h
index 1c8460e23583..283c34647856 100644
--- a/arch/powerpc/include/asm/stackprotector.h
+++ b/arch/powerpc/include/asm/stackprotector.h
@@ -7,8 +7,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H
 
-#include <linux/random.h>
-#include <linux/version.h>
 #include <asm/reg.h>
 #include <asm/current.h>
 #include <asm/paca.h>
@@ -21,13 +19,7 @@
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	canary = get_random_canary();
-	canary ^= mftb();
-	canary ^= LINUX_VERSION_CODE;
-	canary &= CANARY_MASK;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 #ifdef CONFIG_PPC64
diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h
index 09093af46565..43895b90fe3f 100644
--- a/arch/riscv/include/asm/stackprotector.h
+++ b/arch/riscv/include/asm/stackprotector.h
@@ -3,9 +3,6 @@
 #ifndef _ASM_RISCV_STACKPROTECTOR_H
 #define _ASM_RISCV_STACKPROTECTOR_H
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 extern unsigned long __stack_chk_guard;
 
 /*
@@ -16,12 +13,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
-	canary &= CANARY_MASK;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
diff --git a/arch/sh/include/asm/stackprotector.h b/arch/sh/include/asm/stackprotector.h
index 35616841d0a1..665dafac376f 100644
--- a/arch/sh/include/asm/stackprotector.h
+++ b/arch/sh/include/asm/stackprotector.h
@@ -2,9 +2,6 @@
 #ifndef __ASM_SH_STACKPROTECTOR_H
 #define __ASM_SH_STACKPROTECTOR_H
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 extern unsigned long __stack_chk_guard;
 
 /*
@@ -15,12 +12,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
-	canary &= CANARY_MASK;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	__stack_chk_guard = current->stack_canary;
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 24a8d6c4fb18..00473a650f51 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -34,7 +34,6 @@
 #include <asm/percpu.h>
 #include <asm/desc.h>
 
-#include <linux/random.h>
 #include <linux/sched.h>
 
 /*
@@ -50,22 +49,11 @@
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	u64 canary;
-	u64 tsc;
+	unsigned long canary = get_random_canary();
 
 #ifdef CONFIG_X86_64
 	BUILD_BUG_ON(offsetof(struct fixed_percpu_data, stack_canary) != 40);
 #endif
-	/*
-	 * We both use the random pool and the current TSC as a source
-	 * of randomness. The TSC only matters for very early init,
-	 * there it already has some randomness on most systems. Later
-	 * on during the bootup the random pool has true entropy too.
-	 */
-	get_random_bytes(&canary, sizeof(canary));
-	tsc = rdtsc();
-	canary += tsc + (tsc << 32UL);
-	canary &= CANARY_MASK;
 
 	current->stack_canary = canary;
 #ifdef CONFIG_X86_64
diff --git a/arch/xtensa/include/asm/stackprotector.h b/arch/xtensa/include/asm/stackprotector.h
index e368f94fd2af..e1e318a0c98a 100644
--- a/arch/xtensa/include/asm/stackprotector.h
+++ b/arch/xtensa/include/asm/stackprotector.h
@@ -14,7 +14,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H 1
 
-#include <linux/random.h>
 #include <linux/version.h>
 
 extern unsigned long __stack_chk_guard;
@@ -27,11 +26,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	__stack_chk_guard = current->stack_canary;
-- 
2.38.1


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

* Re: [PATCH v1 2/2] stackprotector: actually use get_random_canary()
  2022-10-23 20:32 ` [PATCH v1 2/2] stackprotector: actually use get_random_canary() Jason A. Donenfeld
@ 2022-10-24  0:47   ` Guo Ren
  2022-11-09 17:44   ` Catalin Marinas
  1 sibling, 0 replies; 7+ messages in thread
From: Guo Ren @ 2022-10-24  0:47 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: linux-kernel, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Catalin Marinas, Chris Zankel, Christophe Leroy, Dave Hansen,
	Greg Kroah-Hartman, H . Peter Anvin, Ingo Molnar, Juergen Gross,
	Max Filippov, Michael Ellerman, Nicholas Piggin, Palmer Dabbelt,
	Paul Walmsley, Rich Felker, Russell King, Thomas Bogendoerfer,
	Thomas Gleixner, Will Deacon, Yoshinori Sato, linux-arm-kernel,
	linux-csky, linux-mips, linux-riscv, linux-sh, linux-xtensa,
	linuxppc-dev, x86

On Mon, Oct 24, 2022 at 4:32 AM Jason A. Donenfeld <Jason@zx2c4.com> wrote:
>
> The RNG always mixes in the Linux version extremely early in boot. It
> also always includes a cycle counter, not only during early boot, but
> each and every time it is invoked prior to being fully initialized.
> Together, this means that the use of additional xors inside of the
> various stackprotector.h files is superfluous and over-complicated.
> Instead, we can get exactly the same thing, but better, by just calling
> `get_random_canary()`.
>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  arch/arm/include/asm/stackprotector.h     |  9 +--------
>  arch/arm64/include/asm/stackprotector.h   |  9 +--------
>  arch/csky/include/asm/stackprotector.h    | 10 +---------
>  arch/mips/include/asm/stackprotector.h    |  9 +--------
>  arch/powerpc/include/asm/stackprotector.h | 10 +---------
>  arch/riscv/include/asm/stackprotector.h   | 10 +---------
>  arch/sh/include/asm/stackprotector.h      | 10 +---------
>  arch/x86/include/asm/stackprotector.h     | 14 +-------------
>  arch/xtensa/include/asm/stackprotector.h  |  7 +------
>  9 files changed, 9 insertions(+), 79 deletions(-)
>
> diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
> index 088d03161be5..0bd4979759f1 100644
> --- a/arch/arm/include/asm/stackprotector.h
> +++ b/arch/arm/include/asm/stackprotector.h
> @@ -15,9 +15,6 @@
>  #ifndef _ASM_STACKPROTECTOR_H
>  #define _ASM_STACKPROTECTOR_H 1
>
> -#include <linux/random.h>
> -#include <linux/version.h>
> -
>  #include <asm/thread_info.h>
>
>  extern unsigned long __stack_chk_guard;
> @@ -30,11 +27,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>  #ifndef CONFIG_STACKPROTECTOR_PER_TASK
> diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h
> index 33f1bb453150..ae3ad80f51fe 100644
> --- a/arch/arm64/include/asm/stackprotector.h
> +++ b/arch/arm64/include/asm/stackprotector.h
> @@ -13,8 +13,6 @@
>  #ifndef __ASM_STACKPROTECTOR_H
>  #define __ASM_STACKPROTECTOR_H
>
> -#include <linux/random.h>
> -#include <linux/version.h>
>  #include <asm/pointer_auth.h>
>
>  extern unsigned long __stack_chk_guard;
> @@ -28,12 +26,7 @@ extern unsigned long __stack_chk_guard;
>  static __always_inline void boot_init_stack_canary(void)
>  {
>  #if defined(CONFIG_STACKPROTECTOR)
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> -       canary &= CANARY_MASK;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>         if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
> diff --git a/arch/csky/include/asm/stackprotector.h b/arch/csky/include/asm/stackprotector.h
> index d7cd4e51edd9..d23747447166 100644
> --- a/arch/csky/include/asm/stackprotector.h
> +++ b/arch/csky/include/asm/stackprotector.h
> @@ -2,9 +2,6 @@
>  #ifndef _ASM_STACKPROTECTOR_H
>  #define _ASM_STACKPROTECTOR_H 1
>
> -#include <linux/random.h>
> -#include <linux/version.h>
> -
>  extern unsigned long __stack_chk_guard;
>
>  /*
> @@ -15,12 +12,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> -       canary &= CANARY_MASK;
> +       unsigned long canary = get_random_canary();
Acked-by: Guo Ren <guoren@kernel.org> #csky part

>
>         current->stack_canary = canary;
>         __stack_chk_guard = current->stack_canary;
> diff --git a/arch/mips/include/asm/stackprotector.h b/arch/mips/include/asm/stackprotector.h
> index 68d4be9e1254..518c192ad982 100644
> --- a/arch/mips/include/asm/stackprotector.h
> +++ b/arch/mips/include/asm/stackprotector.h
> @@ -15,9 +15,6 @@
>  #ifndef _ASM_STACKPROTECTOR_H
>  #define _ASM_STACKPROTECTOR_H 1
>
> -#include <linux/random.h>
> -#include <linux/version.h>
> -
>  extern unsigned long __stack_chk_guard;
>
>  /*
> @@ -28,11 +25,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>         __stack_chk_guard = current->stack_canary;
> diff --git a/arch/powerpc/include/asm/stackprotector.h b/arch/powerpc/include/asm/stackprotector.h
> index 1c8460e23583..283c34647856 100644
> --- a/arch/powerpc/include/asm/stackprotector.h
> +++ b/arch/powerpc/include/asm/stackprotector.h
> @@ -7,8 +7,6 @@
>  #ifndef _ASM_STACKPROTECTOR_H
>  #define _ASM_STACKPROTECTOR_H
>
> -#include <linux/random.h>
> -#include <linux/version.h>
>  #include <asm/reg.h>
>  #include <asm/current.h>
>  #include <asm/paca.h>
> @@ -21,13 +19,7 @@
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       canary = get_random_canary();
> -       canary ^= mftb();
> -       canary ^= LINUX_VERSION_CODE;
> -       canary &= CANARY_MASK;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>  #ifdef CONFIG_PPC64
> diff --git a/arch/riscv/include/asm/stackprotector.h b/arch/riscv/include/asm/stackprotector.h
> index 09093af46565..43895b90fe3f 100644
> --- a/arch/riscv/include/asm/stackprotector.h
> +++ b/arch/riscv/include/asm/stackprotector.h
> @@ -3,9 +3,6 @@
>  #ifndef _ASM_RISCV_STACKPROTECTOR_H
>  #define _ASM_RISCV_STACKPROTECTOR_H
>
> -#include <linux/random.h>
> -#include <linux/version.h>
> -
>  extern unsigned long __stack_chk_guard;
>
>  /*
> @@ -16,12 +13,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> -       canary &= CANARY_MASK;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>         if (!IS_ENABLED(CONFIG_STACKPROTECTOR_PER_TASK))
> diff --git a/arch/sh/include/asm/stackprotector.h b/arch/sh/include/asm/stackprotector.h
> index 35616841d0a1..665dafac376f 100644
> --- a/arch/sh/include/asm/stackprotector.h
> +++ b/arch/sh/include/asm/stackprotector.h
> @@ -2,9 +2,6 @@
>  #ifndef __ASM_SH_STACKPROTECTOR_H
>  #define __ASM_SH_STACKPROTECTOR_H
>
> -#include <linux/random.h>
> -#include <linux/version.h>
> -
>  extern unsigned long __stack_chk_guard;
>
>  /*
> @@ -15,12 +12,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> -       canary &= CANARY_MASK;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>         __stack_chk_guard = current->stack_canary;
> diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
> index 24a8d6c4fb18..00473a650f51 100644
> --- a/arch/x86/include/asm/stackprotector.h
> +++ b/arch/x86/include/asm/stackprotector.h
> @@ -34,7 +34,6 @@
>  #include <asm/percpu.h>
>  #include <asm/desc.h>
>
> -#include <linux/random.h>
>  #include <linux/sched.h>
>
>  /*
> @@ -50,22 +49,11 @@
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       u64 canary;
> -       u64 tsc;
> +       unsigned long canary = get_random_canary();
>
>  #ifdef CONFIG_X86_64
>         BUILD_BUG_ON(offsetof(struct fixed_percpu_data, stack_canary) != 40);
>  #endif
> -       /*
> -        * We both use the random pool and the current TSC as a source
> -        * of randomness. The TSC only matters for very early init,
> -        * there it already has some randomness on most systems. Later
> -        * on during the bootup the random pool has true entropy too.
> -        */
> -       get_random_bytes(&canary, sizeof(canary));
> -       tsc = rdtsc();
> -       canary += tsc + (tsc << 32UL);
> -       canary &= CANARY_MASK;
>
>         current->stack_canary = canary;
>  #ifdef CONFIG_X86_64
> diff --git a/arch/xtensa/include/asm/stackprotector.h b/arch/xtensa/include/asm/stackprotector.h
> index e368f94fd2af..e1e318a0c98a 100644
> --- a/arch/xtensa/include/asm/stackprotector.h
> +++ b/arch/xtensa/include/asm/stackprotector.h
> @@ -14,7 +14,6 @@
>  #ifndef _ASM_STACKPROTECTOR_H
>  #define _ASM_STACKPROTECTOR_H 1
>
> -#include <linux/random.h>
>  #include <linux/version.h>
>
>  extern unsigned long __stack_chk_guard;
> @@ -27,11 +26,7 @@ extern unsigned long __stack_chk_guard;
>   */
>  static __always_inline void boot_init_stack_canary(void)
>  {
> -       unsigned long canary;
> -
> -       /* Try to get a semi random initial value. */
> -       get_random_bytes(&canary, sizeof(canary));
> -       canary ^= LINUX_VERSION_CODE;
> +       unsigned long canary = get_random_canary();
>
>         current->stack_canary = canary;
>         __stack_chk_guard = current->stack_canary;
> --
> 2.38.1
>


-- 
Best Regards
 Guo Ren

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

* Re: [PATCH v1 0/2] cleanup stackprotector canary generation
  2022-10-23 20:32 [PATCH v1 0/2] cleanup stackprotector canary generation Jason A. Donenfeld
  2022-10-23 20:32 ` [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h Jason A. Donenfeld
  2022-10-23 20:32 ` [PATCH v1 2/2] stackprotector: actually use get_random_canary() Jason A. Donenfeld
@ 2022-10-24  5:03 ` Greg Kroah-Hartman
  2 siblings, 0 replies; 7+ messages in thread
From: Greg Kroah-Hartman @ 2022-10-24  5:03 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: linux-kernel, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Catalin Marinas, Chris Zankel, Christophe Leroy, Dave Hansen,
	Guo Ren, H . Peter Anvin, Ingo Molnar, Juergen Gross,
	Max Filippov, Michael Ellerman, Nicholas Piggin, Palmer Dabbelt,
	Paul Walmsley, Rich Felker, Russell King, Thomas Bogendoerfer,
	Thomas Gleixner, Will Deacon, Yoshinori Sato, linux-arm-kernel,
	linux-csky, linux-mips, linux-riscv, linux-sh, linux-xtensa,
	linuxppc-dev, x86

On Sun, Oct 23, 2022 at 10:32:06PM +0200, Jason A. Donenfeld wrote:
> Stack canary generation currently lives partially in random.h, where it
> doesn't belong, and is in general a bit overcomplicated. This small
> patchset fixes up both issues. I'll take these in my tree, unless
> somebody else prefers to do so.
> 
> Cc: Albert Ou <aou@eecs.berkeley.edu>
> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Guo Ren <guoren@kernel.org>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Palmer Dabbelt <palmer@dabbelt.com>
> Cc: Paul Walmsley <paul.walmsley@sifive.com>
> Cc: Rich Felker <dalias@libc.org>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will@kernel.org>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-csky@vger.kernel.org
> Cc: linux-mips@vger.kernel.org
> Cc: linux-riscv@lists.infradead.org
> Cc: linux-sh@vger.kernel.org
> Cc: linux-xtensa@linux-xtensa.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: x86@kernel.org

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* Re: [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h
  2022-10-23 20:32 ` [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h Jason A. Donenfeld
@ 2022-10-24  5:25   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-10-24  5:25 UTC (permalink / raw)
  To: Jason A. Donenfeld, linux-kernel
  Cc: Albert Ou, Boris Ostrovsky, Borislav Petkov, Catalin Marinas,
	Chris Zankel, Christophe Leroy, Dave Hansen, Greg Kroah-Hartman,
	Guo Ren, H . Peter Anvin, Ingo Molnar, Juergen Gross,
	Max Filippov, Michael Ellerman, Nicholas Piggin, Palmer Dabbelt,
	Paul Walmsley, Rich Felker, Russell King, Thomas Bogendoerfer,
	Thomas Gleixner, Will Deacon, Yoshinori Sato, linux-arm-kernel,
	linux-csky, linux-mips, linux-riscv, linux-sh, linux-xtensa,
	linuxppc-dev, x86

On 23/10/22 22:32, Jason A. Donenfeld wrote:
> This has nothing to do with random.c and everything to do with stack
> protectors. Yes, it uses randomness. But many things use randomness.
> random.h and random.c are concerned with the generation of randomness,
> not with each and every use. So move this function into the more
> specific stackprotector.h file where it belongs.
> 
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>   arch/x86/kernel/cpu/common.c   |  2 +-
>   arch/x86/kernel/setup_percpu.c |  2 +-
>   arch/x86/kernel/smpboot.c      |  2 +-
>   arch/x86/xen/enlighten_pv.c    |  2 +-
>   include/linux/random.h         | 19 -------------------
>   include/linux/stackprotector.h | 19 +++++++++++++++++++
>   kernel/fork.c                  |  2 +-
>   7 files changed, 24 insertions(+), 24 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


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

* Re: [PATCH v1 2/2] stackprotector: actually use get_random_canary()
  2022-10-23 20:32 ` [PATCH v1 2/2] stackprotector: actually use get_random_canary() Jason A. Donenfeld
  2022-10-24  0:47   ` Guo Ren
@ 2022-11-09 17:44   ` Catalin Marinas
  1 sibling, 0 replies; 7+ messages in thread
From: Catalin Marinas @ 2022-11-09 17:44 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: linux-kernel, Albert Ou, Boris Ostrovsky, Borislav Petkov,
	Chris Zankel, Christophe Leroy, Dave Hansen, Greg Kroah-Hartman,
	Guo Ren, H . Peter Anvin, Ingo Molnar, Juergen Gross,
	Max Filippov, Michael Ellerman, Nicholas Piggin, Palmer Dabbelt,
	Paul Walmsley, Rich Felker, Russell King, Thomas Bogendoerfer,
	Thomas Gleixner, Will Deacon, Yoshinori Sato, linux-arm-kernel,
	linux-csky, linux-mips, linux-riscv, linux-sh, linux-xtensa,
	linuxppc-dev, x86

On Sun, Oct 23, 2022 at 10:32:08PM +0200, Jason A. Donenfeld wrote:
> The RNG always mixes in the Linux version extremely early in boot. It
> also always includes a cycle counter, not only during early boot, but
> each and every time it is invoked prior to being fully initialized.
> Together, this means that the use of additional xors inside of the
> various stackprotector.h files is superfluous and over-complicated.
> Instead, we can get exactly the same thing, but better, by just calling
> `get_random_canary()`.
> 
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  arch/arm/include/asm/stackprotector.h     |  9 +--------
>  arch/arm64/include/asm/stackprotector.h   |  9 +--------

For arm64:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

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

end of thread, other threads:[~2022-11-09 17:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-23 20:32 [PATCH v1 0/2] cleanup stackprotector canary generation Jason A. Donenfeld
2022-10-23 20:32 ` [PATCH v1 1/2] stackprotector: move CANARY_MASK and get_random_canary() into stackprotector.h Jason A. Donenfeld
2022-10-24  5:25   ` Philippe Mathieu-Daudé
2022-10-23 20:32 ` [PATCH v1 2/2] stackprotector: actually use get_random_canary() Jason A. Donenfeld
2022-10-24  0:47   ` Guo Ren
2022-11-09 17:44   ` Catalin Marinas
2022-10-24  5:03 ` [PATCH v1 0/2] cleanup stackprotector canary generation Greg Kroah-Hartman

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