1 /*        $NetBSD: t_backtrace_sandbox.c,v 1.3 2025/01/30 16:13:51 christos Exp $         */
2 
3 /*-
4  * Copyright (c) 2025 Kyle Evans <kevans@FreeBSD.org>
5  *
6  * SPDX-License-Identifier: BSD-2-Clause
7  */
8 #include <sys/cdefs.h>
9 __RCSID("$NetBSD: t_backtrace_sandbox.c,v 1.3 2025/01/30 16:13:51 christos Exp $");
10 
11 #include <sys/param.h>
12 #include <sys/wait.h>
13 #ifdef __FreeBSD__
14 #include <sys/capsicum.h>
15 #define __arraycount(a) nitems(a)
16 #endif
17 
18 #include <execinfo.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 
25 #include <atf-c.h>
26 
27 #define   BT_FUNCTIONS                  10
28 
29 ATF_TC(backtrace_sandbox);
ATF_TC_HEAD(backtrace_sandbox,tc)30 ATF_TC_HEAD(backtrace_sandbox, tc)
31 {
32         atf_tc_set_md_var(tc, "descr",
33               "Test backtrace_sandbox_init(3) in sandbox");
34 #ifndef __FreeBSD__
35           atf_tc_set_md_var(tc, "require.user", "root");
36 #endif
37 }
38 
ATF_TC_BODY(backtrace_sandbox,tc)39 ATF_TC_BODY(backtrace_sandbox, tc)
40 {
41           void *addr[BT_FUNCTIONS];
42           char **syms;
43           size_t frames;
44           pid_t pid;
45           int status;
46 
47           frames = backtrace(addr, __arraycount(addr));
48           ATF_REQUIRE(frames > 0);
49 
50           syms = backtrace_symbols_fmt(addr, frames, "%n");
51           ATF_REQUIRE(strcmp(syms[0], "atfu_backtrace_sandbox_body") == 0);
52 
53           pid = fork();
54           ATF_REQUIRE(pid >= 0);
55 
56           if (pid == 0) {
57 
58                     backtrace_sandbox_init();
59 #ifdef __FreeBSD__
60                     cap_enter();
61 #else
62                     if (chroot("/tmp") != 0)
63                               _exit(EXIT_FAILURE);
64 #endif
65 
66                     syms = backtrace_symbols_fmt(addr, frames, "%n");
67                     if (strcmp(syms[0], "atfu_backtrace_sandbox_body") != 0)
68                               _exit(EXIT_FAILURE);
69 
70                     backtrace_sandbox_fini();
71 
72                     _exit(EXIT_SUCCESS);
73           }
74 
75           (void)wait(&status);
76 
77           if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
78                     atf_tc_fail("resolving symbols in chroot failed");
79 
80 }
81 
ATF_TP_ADD_TCS(tp)82 ATF_TP_ADD_TCS(tp)
83 {
84 
85           ATF_TP_ADD_TC(tp, backtrace_sandbox);
86 
87           return atf_no_error();
88 }
89