2023-04-17 16:03:04

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 0/6] tools/nolibc: add stackprotector support for more architectures

Add stackprotector support for all remaining architectures, except s390.

On s390 the stackprotectors are not supported in "global" mode; only
"sysreg" mode which is not suppored in nolibc.

The series also contains a small optimization to strace output during
execution of nolibc-test.

This series is based on the 20230415-nolibc-updates-4a branch of the
nolibc tree.

Signed-off-by: Thomas Weißschuh <[email protected]>
---
Thomas Weißschuh (6):
selftests/nolibc: reduce syscalls during space padding
tools/nolibc: riscv: add stackprotector support
tools/nolibc: aarch64: add stackprotector support
tools/nolibc: arm: add stackprotector support
tools/nolibc: loongarch: add stackprotector support
tools/nolibc: mips: add stackprotector support

tools/include/nolibc/arch-aarch64.h | 7 ++++++-
tools/include/nolibc/arch-arm.h | 7 ++++++-
tools/include/nolibc/arch-loongarch.h | 7 ++++++-
tools/include/nolibc/arch-mips.h | 8 +++++++-
tools/include/nolibc/arch-riscv.h | 7 ++++++-
tools/testing/selftests/nolibc/Makefile | 5 +++++
tools/testing/selftests/nolibc/nolibc-test.c | 15 +++++++++++----
7 files changed, 47 insertions(+), 9 deletions(-)
---
base-commit: e35214ea9db7477a02e67a8b412e8046534bb97c
change-id: 20230408-nolibc-stackprotector-archs-42244674616e

Best regards,
--
Thomas Weißschuh <[email protected]>


2023-04-17 16:03:09

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 4/6] tools/nolibc: arm: add stackprotector support

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/include/nolibc/arch-arm.h | 7 ++++++-
tools/testing/selftests/nolibc/Makefile | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 2eab1aef321b..202e64f537dc 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -199,10 +199,15 @@ 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"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
{
__asm__ volatile (
+#ifdef NOLIBC_STACKPROTECTOR
+ "bl __stack_chk_init\n" /* initialize stack protector */
+#endif
"pop {%r0}\n" /* argc was in the stack */
"mov %r1, %sp\n" /* argv = sp */

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index d68e96afea80..8feffc790a31 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -83,6 +83,7 @@ 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_riscv = $(CFLAGS_STACKPROTECTOR)
CFLAGS_s390 = -m64
CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \

--
2.40.0

2023-04-17 16:03:23

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 3/6] tools/nolibc: aarch64: add stackprotector support

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/include/nolibc/arch-aarch64.h | 7 ++++++-
tools/testing/selftests/nolibc/Makefile | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 76ef26520c85..6a859131c530 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -172,10 +172,15 @@ 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"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
{
__asm__ volatile (
+#ifdef NOLIBC_STACKPROTECTOR
+ "bl __stack_chk_init\n" /* initialize stack protector */
+#endif
"ldr x0, [sp]\n" /* argc (x0) was in the stack */
"add x1, sp, 8\n" /* argv (x1) = sp */
"lsl x2, x0, 3\n" /* envp (x2) = 8*argc ... */
diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 0a83ad388a16..d68e96afea80 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -82,6 +82,7 @@ CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STKP_arm64 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
CFLAGS_s390 = -m64
CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \

--
2.40.0

2023-04-17 16:04:01

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 5/6] tools/nolibc: loongarch: add stackprotector support

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/include/nolibc/arch-loongarch.h | 7 ++++++-
tools/testing/selftests/nolibc/Makefile | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index ec3b46a991a9..07e3b1fd7262 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -149,6 +149,8 @@
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"
@@ -170,9 +172,12 @@ const unsigned long *_auxv __attribute__((weak));
#endif

/* startup code */
-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
+ "bl __stack_chk_init\n" /* initialize stack protector */
+#endif
REG_L " $a0, $sp, 0\n" /* argc (a0) was in the stack */
LONG_ADDI " $a1, $sp, "SZREG"\n" /* argv (a1) = sp + SZREG */
LONG_SLL " $a2, $a0, "LONGLOG"\n" /* envp (a2) = SZREG*argc ... */
diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 8feffc790a31..efa7a51e0fcd 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -85,6 +85,7 @@ CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_arm64 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_arm = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STKP_loongarch = $(CFLAGS_STACKPROTECTOR)
CFLAGS_s390 = -m64
CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
$(call cc-option,-fno-stack-protector) \

--
2.40.0

2023-04-17 16:04:19

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 6/6] tools/nolibc: mips: add stackprotector support

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/include/nolibc/arch-mips.h | 8 +++++++-
tools/testing/selftests/nolibc/Makefile | 1 +
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 8822f150e72f..65c19ccc7f9d 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -179,14 +179,20 @@ 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"))) __start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) __start(void)
{
__asm__ volatile (
/*".set nomips16\n"*/
".set push\n"
".set noreorder\n"
".option pic0\n"
+#ifdef NOLIBC_STACKPROTECTOR
+ "jal __stack_chk_init\n" /* initialize stack protector */
+ "nop\n" /* delayed slot */
+#endif
/*".ent __start\n"*/
/*"__start:\n"*/
"lw $a0,($sp)\n" /* argc was in the stack */
diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index efa7a51e0fcd..a7524445f33c 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -84,6 +84,7 @@ 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_s390 = -m64

--
2.40.0

2023-04-17 16:04:59

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 2/6] tools/nolibc: riscv: add stackprotector support

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/include/nolibc/arch-riscv.h | 7 ++++++-
tools/testing/selftests/nolibc/Makefile | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 0d5f15fdedc4..b2ccffcc079f 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -173,14 +173,19 @@ 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"))) _start(void)
+void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
{
__asm__ volatile (
".option push\n"
".option norelax\n"
"lla gp, __global_pointer$\n"
".option pop\n"
+#ifdef NOLIBC_STACKPROTECTOR
+ "call __stack_chk_init\n" /* initialize stack protector */
+#endif
"lw a0, 0(sp)\n" /* argc (a0) was in the stack */
"add a1, sp, "SZREG"\n" /* argv (a1) = sp */
"slli a2, a0, "PTRLOG"\n" /* envp (a2) = SZREG*argc ... */
diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 3c8e3a6f8985..0a83ad388a16 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -82,6 +82,7 @@ CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
+CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
CFLAGS_s390 = -m64
CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
$(call cc-option,-fno-stack-protector) \

--
2.40.0

2023-04-17 16:05:04

by Thomas Weißschuh

[permalink] [raw]
Subject: [PATCH 1/6] selftests/nolibc: reduce syscalls during space padding

Previously each space character used for alignment during test execution
was written in a single write() call.
This would make the output from strace fairly unreadable.
Coalesce all spaces into a single call to write().

Signed-off-by: Thomas Weißschuh <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 68e22617651c..35f203556a0c 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -108,19 +108,26 @@ const char *errorname(int err)
}
}

+static void putcharn(char c, size_t n)
+{
+ char buf[64];
+
+ memset(buf, c, n);
+ buf[n] = '\0';
+ fputs(buf, stdout);
+}
+
static int pad_spc(int llen, int cnt, const char *fmt, ...)
{
va_list args;
- int len;
int ret;

- for (len = 0; len < cnt - llen; len++)
- putchar(' ');
+ putcharn(' ', cnt - llen);

va_start(args, fmt);
ret = vfprintf(stdout, fmt, args);
va_end(args);
- return ret < 0 ? ret : ret + len;
+ return ret < 0 ? ret : ret + cnt - llen;
}

/* The tests below are intended to be used by the macroes, which evaluate

--
2.40.0

2023-04-17 19:52:55

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [PATCH 2/6] tools/nolibc: riscv: add stackprotector support

On Mon, 17 Apr 2023 09:01:32 PDT (-0700), [email protected] wrote:
> Signed-off-by: Thomas Weißschuh <[email protected]>
> ---
> tools/include/nolibc/arch-riscv.h | 7 ++++++-
> tools/testing/selftests/nolibc/Makefile | 1 +
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
> index 0d5f15fdedc4..b2ccffcc079f 100644
> --- a/tools/include/nolibc/arch-riscv.h
> +++ b/tools/include/nolibc/arch-riscv.h
> @@ -173,14 +173,19 @@ 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"))) _start(void)
> +void __attribute__((weak,noreturn,optimize("omit-frame-pointer"),no_stack_protector)) _start(void)
> {
> __asm__ volatile (
> ".option push\n"
> ".option norelax\n"
> "lla gp, __global_pointer$\n"
> ".option pop\n"
> +#ifdef NOLIBC_STACKPROTECTOR
> + "call __stack_chk_init\n" /* initialize stack protector */
> +#endif
> "lw a0, 0(sp)\n" /* argc (a0) was in the stack */
> "add a1, sp, "SZREG"\n" /* argv (a1) = sp */
> "slli a2, a0, "PTRLOG"\n" /* envp (a2) = SZREG*argc ... */
> diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
> index 3c8e3a6f8985..0a83ad388a16 100644
> --- a/tools/testing/selftests/nolibc/Makefile
> +++ b/tools/testing/selftests/nolibc/Makefile
> @@ -82,6 +82,7 @@ CFLAGS_STACKPROTECTOR = -DNOLIBC_STACKPROTECTOR \
> CFLAGS_STKP_i386 = $(CFLAGS_STACKPROTECTOR)
> CFLAGS_STKP_x86_64 = $(CFLAGS_STACKPROTECTOR)
> CFLAGS_STKP_x86 = $(CFLAGS_STACKPROTECTOR)
> +CFLAGS_STKP_riscv = $(CFLAGS_STACKPROTECTOR)
> CFLAGS_s390 = -m64
> CFLAGS ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \
> $(call cc-option,-fno-stack-protector) \

Acked-by: Palmer Dabbelt <[email protected]>