llvm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler
@ 2023-05-21  9:36 Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 1/7] tools/nolibc: fix typo pint -> point Thomas Weißschuh
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

As suggested by Willy it is possible to detect the availability of
stackprotector via preprocessor defines.
Make use of that to simplify the code and interface of nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Thomas Weißschuh (7):
      tools/nolibc: fix typo pint -> point
      tools/nolibc: x86_64: disable stack protector for _start
      tools/nolibc: ensure stack protector guard is never zero
      tools/nolibc: add test for __stack_chk_guard initialization
      tools/nolibc: reformat list of headers to be installed
      tools/nolibc: add autodetection for stackprotector support
      tools/nolibc: simplify stackprotector compiler flags

 tools/include/nolibc/Makefile                | 19 +++++++++++++++++--
 tools/include/nolibc/arch-aarch64.h          |  6 +++---
 tools/include/nolibc/arch-arm.h              |  6 +++---
 tools/include/nolibc/arch-i386.h             |  6 +++---
 tools/include/nolibc/arch-loongarch.h        |  6 +++---
 tools/include/nolibc/arch-mips.h             |  6 +++---
 tools/include/nolibc/arch-riscv.h            |  6 +++---
 tools/include/nolibc/arch-x86_64.h           |  8 ++++----
 tools/include/nolibc/arch.h                  |  2 +-
 tools/include/nolibc/compiler.h              | 15 +++++++++++++++
 tools/include/nolibc/stackprotector.h        | 15 ++++++---------
 tools/testing/selftests/nolibc/Makefile      | 13 ++-----------
 tools/testing/selftests/nolibc/nolibc-test.c | 10 +++++++++-
 13 files changed, 72 insertions(+), 46 deletions(-)
---
base-commit: 606343b7478c319cb30291a39ecbceddb42229d6
change-id: 20230521-nolibc-automatic-stack-protector-b4f7fab9e625

Best regards,
-- 
Thomas Weißschuh <linux@weissschuh.net>


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

* [PATCH 1/7] tools/nolibc: fix typo pint -> point
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 2/7] tools/nolibc: x86_64: disable stack protector for _start Thomas Weißschuh
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/include/nolibc/arch.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
index 2d5386a8d6aa..82b43935650f 100644
--- a/tools/include/nolibc/arch.h
+++ b/tools/include/nolibc/arch.h
@@ -7,7 +7,7 @@
  * the syscall declarations and the _start code definition. This is the only
  * global part. On all architectures the kernel puts everything in the stack
  * before jumping to _start just above us, without any return address (_start
- * is not a function but an entry pint). So at the stack pointer we find argc.
+ * is not a function but an entry point). So at the stack pointer we find argc.
  * Then argv[] begins, and ends at the first NULL. Then we have envp which
  * starts and ends with a NULL as well. So envp=argv+argc+1.
  */

-- 
2.40.1


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

* [PATCH 2/7] tools/nolibc: x86_64: disable stack protector for _start
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 1/7] tools/nolibc: fix typo pint -> point Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 3/7] tools/nolibc: ensure stack protector guard is never zero Thomas Weißschuh
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

This was forgotten in the original submission.

It is unknown why it worked for x86_64 on some compiler without this
attribute.

Reported-by: Willy Tarreau <w@1wt.eu>
Closes: https://lore.kernel.org/lkml/20230520133237.GA27501@1wt.eu/
Fixes: 0d8c461adbc4 ("tools/nolibc: x86_64: add stackprotector support")
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/include/nolibc/arch-x86_64.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index d98f6c89d143..e201af15e142 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -190,7 +190,7 @@ const unsigned long *_auxv __attribute__((weak));
  * 2) The deepest stack frame should be zero (the %rbp).
  *
  */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
 #ifdef NOLIBC_STACKPROTECTOR

-- 
2.40.1


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

* [PATCH 3/7] tools/nolibc: ensure stack protector guard is never zero
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 1/7] tools/nolibc: fix typo pint -> point Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 2/7] tools/nolibc: x86_64: disable stack protector for _start Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 4/7] tools/nolibc: add test for __stack_chk_guard initialization Thomas Weißschuh
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

The all-zero pattern is one of the more probable out-of-bound writes so
add a special case to not accidentally accept it.

Also it enables the reliable detection of stack protector initialization
during testing.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/include/nolibc/stackprotector.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
index 77e5251c4490..b0156fc077a0 100644
--- a/tools/include/nolibc/stackprotector.h
+++ b/tools/include/nolibc/stackprotector.h
@@ -45,8 +45,9 @@ __attribute__((weak,no_stack_protector,section(".text.nolibc_stack_chk")))
 void __stack_chk_init(void)
 {
 	my_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
-	/* a bit more randomness in case getrandom() fails */
-	__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
+	/* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
+	if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
+		__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
 }
 #endif /* defined(NOLIBC_STACKPROTECTOR) */
 

-- 
2.40.1


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

* [PATCH 4/7] tools/nolibc: add test for __stack_chk_guard initialization
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
                   ` (2 preceding siblings ...)
  2023-05-21  9:36 ` [PATCH 3/7] tools/nolibc: ensure stack protector guard is never zero Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 5/7] tools/nolibc: reformat list of headers to be installed Thomas Weißschuh
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index d8b59c8f6c03..995dc39a177e 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -808,6 +808,14 @@ static int run_protection(int min, int max)
 	return 0;
 #endif
 
+#if defined(NOLIBC_STACKPROTECTOR)
+	if (!__stack_chk_guard) {
+		llen += printf("__stack_chk_guard not initialized");
+		pad_spc(llen, 64, "[FAIL]\n");
+		return 1;
+	}
+#endif
+
 	pid = -1;
 	pid = fork();
 

-- 
2.40.1


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

* [PATCH 5/7] tools/nolibc: reformat list of headers to be installed
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
                   ` (3 preceding siblings ...)
  2023-05-21  9:36 ` [PATCH 4/7] tools/nolibc: add test for __stack_chk_guard initialization Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 6/7] tools/nolibc: add autodetection for stackprotector support Thomas Weißschuh
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

This makes it easier to add and remove more entries in the future
without creating spurious diff hunks.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/include/nolibc/Makefile | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index 9839feafd38a..e37c3ac86e23 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -25,8 +25,22 @@ endif
 
 nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
 arch_file := arch-$(nolibc_arch).h
-all_files := ctype.h errno.h nolibc.h signal.h stackprotector.h std.h stdint.h \
-             stdio.h stdlib.h string.h sys.h time.h types.h unistd.h
+all_files := \
+		ctype.h \
+		errno.h \
+		nolibc.h \
+		signal.h \
+		stackprotector.h \
+		std.h \
+		stdint.h \
+		stdlib.h \
+		string.h \
+		sys.h \
+		time.h \
+		types.h \
+		unistd.h \
+		stdio.h \
+
 
 # install all headers needed to support a bare-metal compiler
 all: headers

-- 
2.40.1


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

* [PATCH 6/7] tools/nolibc: add autodetection for stackprotector support
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
                   ` (4 preceding siblings ...)
  2023-05-21  9:36 ` [PATCH 5/7] tools/nolibc: reformat list of headers to be installed Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21  9:36 ` [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags Thomas Weißschuh
  2023-05-21 10:08 ` [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Willy Tarreau
  7 siblings, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

The stackprotector support in nolibc should be enabled iff it is also
enabled in the compiler.
Use the preprocessor defines added by gcc and clang if stackprotector
support is enable to automatically do so in nolibc.

This completely removes the need for any user-visible API.

To avoid inlining the lengthy preprocessor check into every user
introduce a new header compiler.h that abstracts the logic away.

As the define NOLIBC_STACKPROTECTOR is now not user-relevant anymore
prefix it with an underscore.

Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/lkml/20230520133237.GA27501@1wt.eu/
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/include/nolibc/Makefile                |  1 +
 tools/include/nolibc/arch-aarch64.h          |  6 +++---
 tools/include/nolibc/arch-arm.h              |  6 +++---
 tools/include/nolibc/arch-i386.h             |  6 +++---
 tools/include/nolibc/arch-loongarch.h        |  6 +++---
 tools/include/nolibc/arch-mips.h             |  6 +++---
 tools/include/nolibc/arch-riscv.h            |  6 +++---
 tools/include/nolibc/arch-x86_64.h           |  6 +++---
 tools/include/nolibc/compiler.h              | 15 +++++++++++++++
 tools/include/nolibc/stackprotector.h        | 10 +++-------
 tools/testing/selftests/nolibc/nolibc-test.c |  4 ++--
 11 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index e37c3ac86e23..64d67b080744 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -26,6 +26,7 @@ endif
 nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
 arch_file := arch-$(nolibc_arch).h
 all_files := \
+		compiler.h \
 		ctype.h \
 		errno.h \
 		nolibc.h \
diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 6a859131c530..64ec65b4ee38 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_AARCH64_H
 #define _NOLIBC_ARCH_AARCH64_H
 
+#include "compiler.h"
+
 /* The struct returned by the newfstatat() syscall. Differs slightly from the
  * x86_64's stat one by field ordering, so be careful.
  */
@@ -172,13 +174,11 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code */
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"bl __stack_chk_init\n"   /* initialize stack protector                     */
 #endif
 		"ldr x0, [sp]\n"     /* argc (x0) was in the stack                          */
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 202e64f537dc..924169522cf7 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_ARM_H
 #define _NOLIBC_ARCH_ARM_H
 
+#include "compiler.h"
+
 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
  * exactly 56 bytes (stops before the unused array). In big endian, the format
  * differs as devices are returned as short only.
@@ -199,13 +201,11 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code */
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"bl __stack_chk_init\n"       /* initialize stack protector                          */
 #endif
 		"pop {%r0}\n"                 /* argc was in the stack                               */
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index 7c41897a08ce..37f813912957 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_I386_H
 #define _NOLIBC_ARCH_I386_H
 
+#include "compiler.h"
+
 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
  * exactly 56 bytes (stops before the unused array).
  */
@@ -181,8 +183,6 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code */
 /*
  * i386 System V ABI mandates:
@@ -193,7 +193,7 @@ const unsigned long *_auxv __attribute__((weak));
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"call __stack_chk_init\n"   /* initialize stack protector                    */
 #endif
 		"pop %eax\n"                /* argc   (first arg, %eax)                      */
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index 07e3b1fd7262..d8ea7e787df4 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_LOONGARCH_H
 #define _NOLIBC_ARCH_LOONGARCH_H
 
+#include "compiler.h"
+
 /* Syscalls for LoongArch :
  *   - stack is 16-byte aligned
  *   - syscall number is passed in a7
@@ -149,8 +151,6 @@
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 #if __loongarch_grlen == 32
 #define LONGLOG      "2"
 #define SZREG        "4"
@@ -175,7 +175,7 @@ const unsigned long *_auxv __attribute__((weak));
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"bl __stack_chk_init\n"               /* initialize stack protector                          */
 #endif
 		REG_L        " $a0, $sp, 0\n"         /* argc (a0) was in the stack                          */
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 65c19ccc7f9d..9860236e5340 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_MIPS_H
 #define _NOLIBC_ARCH_MIPS_H
 
+#include "compiler.h"
+
 /* The struct returned by the stat() syscall. 88 bytes are returned by the
  * syscall.
  */
@@ -179,8 +181,6 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code, note that it's called __start on MIPS */
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) __start(void)
 {
@@ -189,7 +189,7 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protec
 		".set push\n"
 		".set    noreorder\n"
 		".option pic0\n"
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"jal __stack_chk_init\n" /* initialize stack protector                         */
 		"nop\n"                  /* delayed slot                                       */
 #endif
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index d0439249c9c9..86616aeb77a0 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_RISCV_H
 #define _NOLIBC_ARCH_RISCV_H
 
+#include "compiler.h"
+
 struct sys_stat_struct {
 	unsigned long	st_dev;		/* Device.  */
 	unsigned long	st_ino;		/* File serial number.  */
@@ -177,8 +179,6 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code */
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
@@ -187,7 +187,7 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protec
 		".option norelax\n"
 		"lla   gp, __global_pointer$\n"
 		".option pop\n"
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"call __stack_chk_init\n"    /* initialize stack protector                          */
 #endif
 		REG_L" a0, 0(sp)\n"          /* argc (a0) was in the stack                          */
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index e201af15e142..485a7ff72a87 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -7,6 +7,8 @@
 #ifndef _NOLIBC_ARCH_X86_64_H
 #define _NOLIBC_ARCH_X86_64_H
 
+#include "compiler.h"
+
 /* The struct returned by the stat() syscall, equivalent to stat64(). The
  * syscall returns 116 bytes and stops in the middle of __unused.
  */
@@ -181,8 +183,6 @@ struct sys_stat_struct {
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-#define __ARCH_SUPPORTS_STACK_PROTECTOR
-
 /* startup code */
 /*
  * x86-64 System V ABI mandates:
@@ -193,7 +193,7 @@ const unsigned long *_auxv __attribute__((weak));
 void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
 {
 	__asm__ volatile (
-#ifdef NOLIBC_STACKPROTECTOR
+#ifdef _NOLIBC_STACKPROTECTOR
 		"call __stack_chk_init\n"   /* initialize stack protector                          */
 #endif
 		"pop %rdi\n"                /* argc   (first arg, %rdi)                            */
diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
new file mode 100644
index 000000000000..57da75cea799
--- /dev/null
+++ b/tools/include/nolibc/compiler.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * NOLIBC compiler support header
+ * Copyright (C) 2023 Thomas Weißschuh <linux@weissschuh.net>
+ */
+#ifndef _NOLIBC_COMPILER_H
+#define _NOLIBC_COMPILER_H
+
+#if defined(__SSP__) || defined(__SSP_STRONG__) || defined(__SSP_ALL__) || defined(__SSP_EXPLICIT__)
+
+#define _NOLIBC_STACKPROTECTOR
+
+#endif /* defined(__SSP__) ... */
+
+#endif /* _NOLIBC_COMPILER_H */
diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
index b0156fc077a0..0a89e2b89ca6 100644
--- a/tools/include/nolibc/stackprotector.h
+++ b/tools/include/nolibc/stackprotector.h
@@ -7,13 +7,9 @@
 #ifndef _NOLIBC_STACKPROTECTOR_H
 #define _NOLIBC_STACKPROTECTOR_H
 
-#include "arch.h"
+#include "compiler.h"
 
-#if defined(NOLIBC_STACKPROTECTOR)
-
-#if !defined(__ARCH_SUPPORTS_STACK_PROTECTOR)
-#error "nolibc does not support stack protectors on this arch"
-#endif
+#if defined(_NOLIBC_STACKPROTECTOR)
 
 #include "sys.h"
 #include "stdlib.h"
@@ -49,6 +45,6 @@ void __stack_chk_init(void)
 	if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
 		__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
 }
-#endif /* defined(NOLIBC_STACKPROTECTOR) */
+#endif /* defined(_NOLIBC_STACKPROTECTOR) */
 
 #endif /* _NOLIBC_STACKPROTECTOR_H */
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 995dc39a177e..6e0a4dbe321e 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -802,13 +802,13 @@ static int run_protection(int min, int max)
 
 	llen += printf("0 -fstackprotector ");
 
-#if !defined(NOLIBC_STACKPROTECTOR)
+#if !defined(_NOLIBC_STACKPROTECTOR)
 	llen += printf("not supported");
 	pad_spc(llen, 64, "[SKIPPED]\n");
 	return 0;
 #endif
 
-#if defined(NOLIBC_STACKPROTECTOR)
+#if defined(_NOLIBC_STACKPROTECTOR)
 	if (!__stack_chk_guard) {
 		llen += printf("__stack_chk_guard not initialized");
 		pad_spc(llen, 64, "[FAIL]\n");

-- 
2.40.1


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

* [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
                   ` (5 preceding siblings ...)
  2023-05-21  9:36 ` [PATCH 6/7] tools/nolibc: add autodetection for stackprotector support Thomas Weißschuh
@ 2023-05-21  9:36 ` Thomas Weißschuh
  2023-05-21 10:36   ` Thomas Weißschuh
  2023-05-23 20:12   ` Willy Tarreau
  2023-05-21 10:08 ` [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Willy Tarreau
  7 siblings, 2 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21  9:36 UTC (permalink / raw)
  To: Willy Tarreau, Paul E. McKenney, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Nathan Chancellor, Nick Desaulniers,
	Tom Rix
  Cc: linux-kernel, linux-kselftest, linux-riscv, llvm, Thomas Weißschuh

Now that nolibc enable stackprotector support automatically when the
compiler enables it we only have to get the -fstack-protector flags
correct.

The cc-options are structured so that -fstack-protector-all is only
enabled if -mstack-protector=guard works, as that is the only mode
supported by nolibc.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 tools/testing/selftests/nolibc/Makefile | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index bd41102ea299..445c352b1b33 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -76,20 +76,11 @@ else
 Q=@
 endif
 
-CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
-			$(call cc-option,-mstack-protector-guard=global) \
-			$(call cc-option,-fstack-protector-all)
-CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_arm64 = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_arm = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_mips = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
-CFLAGS_STKP_loongarch = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STACKPROTECTOR = $(call cc-option,-mstack-protector-guard=global -fstack-protector-all)
 CFLAGS_s390 = -m64
 CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
 		$(call cc-option,-fno-stack-protector) \
+		$(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all)) \
 		$(CFLAGS_STKP_$(ARCH)) $(CFLAGS_$(ARCH))
 LDFLAGS := -s
 

-- 
2.40.1


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

* Re: [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler
  2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
                   ` (6 preceding siblings ...)
  2023-05-21  9:36 ` [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags Thomas Weißschuh
@ 2023-05-21 10:08 ` Willy Tarreau
  7 siblings, 0 replies; 11+ messages in thread
From: Willy Tarreau @ 2023-05-21 10:08 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Paul E. McKenney, Shuah Khan, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Nathan Chancellor, Nick Desaulniers, Tom Rix,
	linux-kernel, linux-kselftest, linux-riscv, llvm

Hi Thomas,

On Sun, May 21, 2023 at 11:36:28AM +0200, Thomas Weißschuh wrote:
> As suggested by Willy it is possible to detect the availability of
> stackprotector via preprocessor defines.
> Make use of that to simplify the code and interface of nolibc.

I have just had a quick glance over it and not tested it yet, but
overall I really like it, thank you! I'll try to give you some
feedback today (or simply merge it).

Willy

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

* Re: [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags
  2023-05-21  9:36 ` [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags Thomas Weißschuh
@ 2023-05-21 10:36   ` Thomas Weißschuh
  2023-05-23 20:12   ` Willy Tarreau
  1 sibling, 0 replies; 11+ messages in thread
From: Thomas Weißschuh @ 2023-05-21 10:36 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: Paul E. McKenney, Shuah Khan, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Nathan Chancellor, Nick Desaulniers, Tom Rix,
	linux-kernel, linux-kselftest, linux-riscv, llvm

On 2023-05-21 11:36:35+0200, Thomas Weißschuh wrote:
> Now that nolibc enable stackprotector support automatically when the
> compiler enables it we only have to get the -fstack-protector flags
> correct.
> 
> The cc-options are structured so that -fstack-protector-all is only
> enabled if -mstack-protector=guard works, as that is the only mode
> supported by nolibc.
> 
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
>  tools/testing/selftests/nolibc/Makefile | 13 ++-----------
>  1 file changed, 2 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
> index bd41102ea299..445c352b1b33 100644
> --- a/tools/testing/selftests/nolibc/Makefile
> +++ b/tools/testing/selftests/nolibc/Makefile
> @@ -76,20 +76,11 @@ else
>  Q=@
>  endif
>  
> -CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
> -			$(call cc-option,-mstack-protector-guard=global) \
> -			$(call cc-option,-fstack-protector-all)
> -CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_arm64 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_arm = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_mips = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_loongarch = $(CFLAGS_STACKPROTECTOR)
> +CFLAGS_STACKPROTECTOR = $(call cc-option,-mstack-protector-guard=global -fstack-protector-all)
>  CFLAGS_s390 = -m64
>  CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
>  		$(call cc-option,-fno-stack-protector) \
> +		$(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all)) \
>  		$(CFLAGS_STKP_$(ARCH)) $(CFLAGS_$(ARCH))
>  LDFLAGS := -s

I noticed, of course after having sent the series, that the cleanup here
was not done properly.

CFLAGS_STACKPROTECTOR and CFLAGS_STKP should be deleted completely.

This will be fixed in v2, or feel free to fix it up when applying the
series.

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

* Re: [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags
  2023-05-21  9:36 ` [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags Thomas Weißschuh
  2023-05-21 10:36   ` Thomas Weißschuh
@ 2023-05-23 20:12   ` Willy Tarreau
  1 sibling, 0 replies; 11+ messages in thread
From: Willy Tarreau @ 2023-05-23 20:12 UTC (permalink / raw)
  To: Thomas Weißschuh, Zhangjin Wu
  Cc: Paul E. McKenney, Shuah Khan, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Nathan Chancellor, Nick Desaulniers, Tom Rix,
	linux-kernel, linux-kselftest, linux-riscv, llvm

Hi Thomas, Zhangjin,

I merged and pushed this series on top of the previous series, it's in
branch 20230523-nolibc-rv32+stkp3.

However, Thomas, I found an issue with this last patch that I partially
reverted in a last patch I pushed as well so that we can discuss it:

On Sun, May 21, 2023 at 11:36:35AM +0200, Thomas Weißschuh wrote:
>  
> -CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
> -			$(call cc-option,-mstack-protector-guard=global) \
> -			$(call cc-option,-fstack-protector-all)
> -CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_arm64 = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_arm = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_mips = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
> -CFLAGS_STKP_loongarch = $(CFLAGS_STACKPROTECTOR)
> +CFLAGS_STACKPROTECTOR = $(call cc-option,-mstack-protector-guard=global -fstack-protector-all)
>  CFLAGS_s390 = -m64
>  CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
>  		$(call cc-option,-fno-stack-protector) \
> +		$(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all)) \
>  		$(CFLAGS_STKP_$(ARCH)) $(CFLAGS_$(ARCH))

By doing so, we reintroduce the forced stack-protector mechanism
that cannot be disabled anymore. The ability to disable it was the
main point of the options above. In fact checking __SSP__* was a
solution to save the user from having to set -DNOLIBC_STACKPROTECTOR
to match their compiler's flags, but here in the nolibc-test we still
want to be able to forcefully disable stkp for a run (at least to
unbreak gcc-9, and possibly to confirm that non-stkp builds still
continue to work when your local toolchain has it by default).

So I reverted that part and only dropped -DNOLIBC_STACKPROTECTOR.
This way I could run the test on all archs with gcc-9 by forcing
CFLAGS_STACKPROTECTOR= and verified it was still possible to
disable it for a specific arch only by setting CFLAGS_STKP_$ARCH.

If you're fine with this we can squash this one into your cleanup
patch.

Zhangjin I think this branch should work well enough for you to
serve as a base for your upcoming series. We'll clean it up later
once we all agree on the stat() replacement for syscall() and on
the various remaining points including your time32 alternatives.

Thanks to you both,
Willy

PS: we're still carrying a long CC list of individuals who are likely
    not that much interested in our discussion, I propose that we trim
    it on next exchanges and only keep us 3 and the lists, in order to
    remove some of their e-mail pollution.


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

end of thread, other threads:[~2023-05-23 20:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-21  9:36 [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 1/7] tools/nolibc: fix typo pint -> point Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 2/7] tools/nolibc: x86_64: disable stack protector for _start Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 3/7] tools/nolibc: ensure stack protector guard is never zero Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 4/7] tools/nolibc: add test for __stack_chk_guard initialization Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 5/7] tools/nolibc: reformat list of headers to be installed Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 6/7] tools/nolibc: add autodetection for stackprotector support Thomas Weißschuh
2023-05-21  9:36 ` [PATCH 7/7] tools/nolibc: simplify stackprotector compiler flags Thomas Weißschuh
2023-05-21 10:36   ` Thomas Weißschuh
2023-05-23 20:12   ` Willy Tarreau
2023-05-21 10:08 ` [PATCH 0/7] tools/nolibc: autodetect stackprotector availability from compiler Willy Tarreau

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