summaryrefslogtreecommitdiff
path: root/tests/lib/libexecinfo
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2022-07-25 10:38:17 +0000
committerriastradh <riastradh@NetBSD.org>2022-07-25 10:38:17 +0000
commit13fb38ed33b1a5ec99a6bb3595b12f0675907b53 (patch)
tree67b9abc88f7a1d48cff57fddfb9ecc85cd46b21c /tests/lib/libexecinfo
parent0466332097198228db2cf917be221986c5eff3dc (diff)
execinfo: Test stack traces through null pointer jump too.
Diffstat (limited to 'tests/lib/libexecinfo')
-rw-r--r--tests/lib/libexecinfo/t_sig_backtrace.c70
1 files changed, 59 insertions, 11 deletions
diff --git a/tests/lib/libexecinfo/t_sig_backtrace.c b/tests/lib/libexecinfo/t_sig_backtrace.c
index bf6811331ee..4113935ccc3 100644
--- a/tests/lib/libexecinfo/t_sig_backtrace.c
+++ b/tests/lib/libexecinfo/t_sig_backtrace.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_sig_backtrace.c,v 1.2 2021/11/23 23:29:55 thorpej Exp $ */
+/* $NetBSD: t_sig_backtrace.c,v 1.3 2022/07/25 10:38:17 riastradh Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_sig_backtrace.c,v 1.2 2021/11/23 23:29:55 thorpej Exp $");
+__RCSID("$NetBSD: t_sig_backtrace.c,v 1.3 2022/07/25 10:38:17 riastradh Exp $");
#include <sys/mman.h>
#include <execinfo.h>
@@ -48,8 +48,10 @@ __RCSID("$NetBSD: t_sig_backtrace.c,v 1.2 2021/11/23 23:29:55 thorpej Exp $");
stack_t sig_stack;
char *foo;
+char *(*bar)(void);
-static int the_loop(int);
+static int the_loop_deref(int);
+static int the_loop_jump(int);
#ifdef NOINLINE_HACK
volatile int noinline;
@@ -59,7 +61,7 @@ static int __noinline
func1(int i)
{
if (i > 100) {
- return the_loop(i);
+ return the_loop_deref(i);
}
return i + 1;
}
@@ -81,7 +83,7 @@ func3(int i)
}
static int __noinline
-the_loop(int i)
+the_loop_deref(int i)
{
while (*foo != 0) {
i = func3(i);
@@ -97,6 +99,23 @@ the_loop(int i)
return i;
}
+static int __noinline
+the_loop_jump(int i)
+{
+ while ((*bar)() != 0) {
+ i = func3(i);
+ i = func1(i);
+ i = func2(i);
+ }
+
+#ifdef NOINLINE_HACK
+ if (noinline)
+ vfork();
+#endif
+
+ return i;
+}
+
jmp_buf env;
static void
@@ -155,14 +174,42 @@ handler(int s)
longjmp(env, 1);
}
-ATF_TC(sig_backtrace);
-ATF_TC_HEAD(sig_backtrace, tc)
+ATF_TC(sig_backtrace_deref);
+ATF_TC_HEAD(sig_backtrace_deref, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test backtrace(3) across signal handlers, null pointer deref");
+}
+
+ATF_TC_BODY(sig_backtrace_deref, tc)
+{
+ sig_stack.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_STACK, -1, 0);
+ ATF_REQUIRE(sig_stack.ss_sp != MAP_FAILED);
+
+ sig_stack.ss_size = SIGSTKSZ;
+ sig_stack.ss_flags = 0;
+ ATF_REQUIRE(sigaltstack(&sig_stack, NULL) == 0);
+
+ struct sigaction sa = {
+ .sa_handler = handler,
+ .sa_flags = SA_ONSTACK,
+ };
+ ATF_REQUIRE(sigaction(SIGSEGV, &sa, NULL) == 0);
+
+ if (setjmp(env) == 0) {
+ printf("%d\n", the_loop_deref(0));
+ }
+}
+
+ATF_TC(sig_backtrace_jump);
+ATF_TC_HEAD(sig_backtrace_jump, tc)
{
atf_tc_set_md_var(tc, "descr",
- "Test backtrace(3) across signal handlers");
+ "Test backtrace(3) across signal handlers, null pointer jump");
}
-ATF_TC_BODY(sig_backtrace, tc)
+ATF_TC_BODY(sig_backtrace_jump, tc)
{
sig_stack.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_STACK, -1, 0);
@@ -179,13 +226,14 @@ ATF_TC_BODY(sig_backtrace, tc)
ATF_REQUIRE(sigaction(SIGSEGV, &sa, NULL) == 0);
if (setjmp(env) == 0) {
- printf("%d\n", the_loop(0));
+ printf("%d\n", the_loop_jump(0));
}
}
ATF_TP_ADD_TCS(tp)
{
- ATF_TP_ADD_TC(tp, sig_backtrace);
+ ATF_TP_ADD_TC(tp, sig_backtrace_deref);
+ ATF_TP_ADD_TC(tp, sig_backtrace_jump);
return atf_no_error();
}