[RFC PATCH v1 40/50] arch/*/include/asm/stackprotector.h: Use get_random_canary() consistently

Subsystems: arm port, arm64 port (aarch64 architecture), linux for powerpc (32-bit and 64-bit), mips, superh, tensilica xtensa port (xtensa), the rest, x86 architecture (32-bit and 64-bit)

STALE2337d

2 messages, 2 authors, 2020-04-20 · open the first message on its own page

[RFC PATCH v1 40/50] arch/*/include/asm/stackprotector.h: Use get_random_canary() consistently

From: George Spelvin <hidden>
Date: 2020-03-28 16:44:53

... in boot_init_stack_canary().

This is the archetypical example of where the extra security of
get_random_bytes() is wasted.  The canary is only important as
long as it's stored in __stack_chk_guard.

It's also a great example of code that has been copied around
a lot and not updated.

Remove the XOR with LINUX_VERSION_CODE as it's pointless; the inclusion
of utsname() in init_std_data in the random seeding obviates it.

The XOR with the TSC on x86 and mtfb() on powerPC were left in,
as I haven't proved them redundant yet.  For those, we call
get_random_long(), xor, and mask manually.

FUNCTIONAL CHANGE: mips and xtensa were changed from 64-bit
get_random_long() to 56-bit get_random_canary() to match the
others, in accordance with the logic in CANARY_MASK.

(We could do 1 bit better and zero *one* of the two high bytes.)

Signed-off-by: George Spelvin <redacted>
Cc: Russell King <linux@armlinux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ralf Baechle <redacted>
Cc: Paul Burton <paulburton@kernel.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc:  "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
---
 arch/arm/include/asm/stackprotector.h     | 9 +++------
 arch/arm64/include/asm/stackprotector.h   | 8 ++------
 arch/mips/include/asm/stackprotector.h    | 7 ++-----
 arch/powerpc/include/asm/stackprotector.h | 6 ++----
 arch/sh/include/asm/stackprotector.h      | 8 ++------
 arch/x86/include/asm/stackprotector.h     | 4 ++--
 arch/xtensa/include/asm/stackprotector.h  | 7 ++-----
 7 files changed, 15 insertions(+), 34 deletions(-)
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
index 72a20c3a0a90b..88c66fec1b5f4 100644
--- a/arch/arm/include/asm/stackprotector.h
+++ b/arch/arm/include/asm/stackprotector.h
@@ -30,17 +30,14 @@ 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
-	__stack_chk_guard = current->stack_canary;
+	__stack_chk_guard = canary;
 #else
-	current_thread_info()->stack_canary = current->stack_canary;
+	current_thread_info()->stack_canary = canary;
 #endif
 }
 
diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h
index 5884a2b028277..705f60b9df85e 100644
--- a/arch/arm64/include/asm/stackprotector.h
+++ b/arch/arm64/include/asm/stackprotector.h
@@ -26,16 +26,12 @@ 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))
-		__stack_chk_guard = current->stack_canary;
+		__stack_chk_guard = canary;
 }
 
 #endif	/* _ASM_STACKPROTECTOR_H */
diff --git a/arch/mips/include/asm/stackprotector.h b/arch/mips/include/asm/stackprotector.h
index 68d4be9e12547..6d1e4652152bc 100644
--- a/arch/mips/include/asm/stackprotector.h
+++ b/arch/mips/include/asm/stackprotector.h
@@ -28,14 +28,11 @@ 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;
+	__stack_chk_guard = canary;
 }
 
 #endif	/* _ASM_STACKPROTECTOR_H */
diff --git a/arch/powerpc/include/asm/stackprotector.h b/arch/powerpc/include/asm/stackprotector.h
index 1c8460e235838..76577b72ef736 100644
--- a/arch/powerpc/include/asm/stackprotector.h
+++ b/arch/powerpc/include/asm/stackprotector.h
@@ -21,12 +21,10 @@
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
 	/* Try to get a semi random initial value. */
-	canary = get_random_canary();
+	unsigned long canary = get_random_long();
+
 	canary ^= mftb();
-	canary ^= LINUX_VERSION_CODE;
 	canary &= CANARY_MASK;
 
 	current->stack_canary = canary;
diff --git a/arch/sh/include/asm/stackprotector.h b/arch/sh/include/asm/stackprotector.h
index 35616841d0a1c..a9ef619c8a0ec 100644
--- a/arch/sh/include/asm/stackprotector.h
+++ b/arch/sh/include/asm/stackprotector.h
@@ -15,15 +15,11 @@ 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;
+	__stack_chk_guard = canary;
 }
 
 #endif /* __ASM_SH_STACKPROTECTOR_H */
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 91e29b6a86a5e..af74fd3130cf4 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -72,9 +72,9 @@ static __always_inline void boot_init_stack_canary(void)
 	 * 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));
+	canary = get_random_u64();
 	tsc = rdtsc();
-	canary += tsc + (tsc << 32UL);
+	canary += tsc + (tsc << 32);
 	canary &= CANARY_MASK;
 
 	current->stack_canary = canary;
diff --git a/arch/xtensa/include/asm/stackprotector.h b/arch/xtensa/include/asm/stackprotector.h
index e368f94fd2af3..9807fd80e5a8e 100644
--- a/arch/xtensa/include/asm/stackprotector.h
+++ b/arch/xtensa/include/asm/stackprotector.h
@@ -27,14 +27,11 @@ 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;
+	__stack_chk_guard = canary;
 }
 
 #endif	/* _ASM_STACKPROTECTOR_H */
-- 
2.26.0

Re: [RFC PATCH v1 40/50] arch/*/include/asm/stackprotector.h: Use get_random_canary() consistently

From: Will Deacon <will@kernel.org>
Date: 2020-04-20 20:42:47

On Tue, Dec 10, 2019 at 12:35:14AM -0500, George Spelvin wrote:
... in boot_init_stack_canary().

This is the archetypical example of where the extra security of
get_random_bytes() is wasted.  The canary is only important as
long as it's stored in __stack_chk_guard.

It's also a great example of code that has been copied around
a lot and not updated.

Remove the XOR with LINUX_VERSION_CODE as it's pointless; the inclusion
of utsname() in init_std_data in the random seeding obviates it.

The XOR with the TSC on x86 and mtfb() on powerPC were left in,
as I haven't proved them redundant yet.  For those, we call
get_random_long(), xor, and mask manually.

FUNCTIONAL CHANGE: mips and xtensa were changed from 64-bit
get_random_long() to 56-bit get_random_canary() to match the
others, in accordance with the logic in CANARY_MASK.

(We could do 1 bit better and zero *one* of the two high bytes.)

Signed-off-by: George Spelvin <redacted>
Cc: Russell King <linux@armlinux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ralf Baechle <redacted>
Cc: Paul Burton <paulburton@kernel.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <redacted>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc:  "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
---
 arch/arm/include/asm/stackprotector.h     | 9 +++------
 arch/arm64/include/asm/stackprotector.h   | 8 ++------
 arch/mips/include/asm/stackprotector.h    | 7 ++-----
 arch/powerpc/include/asm/stackprotector.h | 6 ++----
 arch/sh/include/asm/stackprotector.h      | 8 ++------
 arch/x86/include/asm/stackprotector.h     | 4 ++--
 arch/xtensa/include/asm/stackprotector.h  | 7 ++-----
 7 files changed, 15 insertions(+), 34 deletions(-)
Just found this kicking around in the depths of my inbox. Is the series
dead?

Will
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help