[PATCH RFC 5/5] tools/nolibc: tests: add test for -fstack-protector

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Test the previously introduce stack protector functionality in nolibc.

Signed-off-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 74 +++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index fb2d4872fac9..4990b2750279 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -45,6 +45,7 @@ char **environ;
 struct test {
 	const char *name;              // test name
 	int (*func)(int min, int max); // handler
+	char skip_by_default;         // don't run by default
 };
 
 #ifndef _NOLIBC_STDLIB_H
@@ -667,6 +668,70 @@ int run_stdlib(int min, int max)
 	return ret;
 }
 
+#if defined(__clang__)
+__attribute__((optnone))
+#elif defined(__GNUC__)
+__attribute__((optimize("O0")))
+#endif
+static int run_smash_stack(int min, int max)
+{
+	char buf[100];
+
+	for (size_t i = 0; i < 200; i++)
+		buf[i] = 15;
+
+	return 1;
+}
+
+int run_stackprotector(int min, int max)
+{
+	int llen = 0;
+
+	llen += printf("0 ");
+
+#if !defined(NOLIBC_STACKPROTECTOR)
+	llen += printf("stack smashing detection not supported");
+	pad_spc(llen, 64, "[SKIPPED]\n");
+	return 0;
+#endif
+
+	pid_t pid = fork();
+
+	switch (pid) {
+	case -1:
+		llen += printf("fork()");
+		pad_spc(llen, 64, "[FAIL]\n");
+		return 1;
+
+	case 0:
+		close(STDOUT_FILENO);
+		close(STDERR_FILENO);
+
+		char *const argv[] = {
+			"/proc/self/exe",
+			"_smash_stack",
+			NULL,
+		};
+		execve("/proc/self/exe", argv, NULL);
+		return 1;
+
+	default: {
+		int status;
+
+		pid = waitpid(pid, &status, 0);
+
+		if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
+			llen += printf("waitpid()");
+			pad_spc(llen, 64, "[FAIL]\n");
+			return 1;
+		}
+		llen += printf("stack smashing detected");
+		pad_spc(llen, 64, " [OK]\n");
+		return 0;
+	}
+	}
+}
+
 /* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
 int prepare(void)
 {
@@ -719,8 +784,11 @@ int prepare(void)
 /* This is the definition of known test names, with their functions */
 static const struct test test_names[] = {
 	/* add new tests here */
-	{ .name = "syscall",   .func = run_syscall  },
-	{ .name = "stdlib",    .func = run_stdlib   },
+	{ .name = "syscall",        .func = run_syscall         },
+	{ .name = "stdlib",         .func = run_stdlib          },
+	{ .name = "stackprotector", .func = run_stackprotector, },
+	{ .name = "_smash_stack",   .func = run_smash_stack,
+	  .skip_by_default = 1                                  },
 	{ 0 }
 };
 
@@ -811,6 +879,8 @@ int main(int argc, char **argv, char **envp)
 	} else {
 		/* no test mentioned, run everything */
 		for (idx = 0; test_names[idx].name; idx++) {
+			if (test_names[idx].skip_by_default)
+				continue;
 			printf("Running test '%s'\n", test_names[idx].name);
 			err = test_names[idx].func(min, max);
 			ret += err;

-- 
2.39.2




[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux