t_proccwd.c revision 1.2.2.2 1 1.2.2.2 christos /* $NetBSD: t_proccwd.c,v 1.2.2.2 2019/06/10 22:10:01 christos Exp $ */
2 1.2.2.2 christos /*-
3 1.2.2.2 christos * Copyright (c) 2019 The NetBSD Foundation, Inc.
4 1.2.2.2 christos * All rights reserved.
5 1.2.2.2 christos *
6 1.2.2.2 christos * Redistribution and use in source and binary forms, with or without
7 1.2.2.2 christos * modification, are permitted provided that the following conditions
8 1.2.2.2 christos * are met:
9 1.2.2.2 christos * 1. Redistributions of source code must retain the above copyright
10 1.2.2.2 christos * notice, this list of conditions and the following disclaimer.
11 1.2.2.2 christos * 2. Redistributions in binary form must reproduce the above copyright
12 1.2.2.2 christos * notice, this list of conditions and the following disclaimer in the
13 1.2.2.2 christos * documentation and/or other materials provided with the distribution.
14 1.2.2.2 christos *
15 1.2.2.2 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 1.2.2.2 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 1.2.2.2 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 1.2.2.2 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 1.2.2.2 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 1.2.2.2 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 1.2.2.2 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 1.2.2.2 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 1.2.2.2 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 1.2.2.2 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 1.2.2.2 christos * POSSIBILITY OF SUCH DAMAGE.
26 1.2.2.2 christos */
27 1.2.2.2 christos
28 1.2.2.2 christos #include <sys/cdefs.h>
29 1.2.2.2 christos __COPYRIGHT("@(#) Copyright (c) 2019\
30 1.2.2.2 christos The NetBSD Foundation, inc. All rights reserved.");
31 1.2.2.2 christos __RCSID("$NetBSD: t_proccwd.c,v 1.2.2.2 2019/06/10 22:10:01 christos Exp $");
32 1.2.2.2 christos
33 1.2.2.2 christos #include <sys/types.h>
34 1.2.2.2 christos #include <sys/stat.h>
35 1.2.2.2 christos #include <sys/sysctl.h>
36 1.2.2.2 christos #include <sys/wait.h>
37 1.2.2.2 christos
38 1.2.2.2 christos #include <errno.h>
39 1.2.2.2 christos #include <stdio.h>
40 1.2.2.2 christos #include <stdlib.h>
41 1.2.2.2 christos #include <string.h>
42 1.2.2.2 christos #include <err.h>
43 1.2.2.2 christos
44 1.2.2.2 christos #include <atf-c.h>
45 1.2.2.2 christos
46 1.2.2.2 christos static int
47 1.2.2.2 christos getproccwd(char *path, size_t *len, pid_t pid)
48 1.2.2.2 christos {
49 1.2.2.2 christos const int name[] = {
50 1.2.2.2 christos CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD,
51 1.2.2.2 christos };
52 1.2.2.2 christos
53 1.2.2.2 christos return sysctl(name, __arraycount(name), path, len, NULL, 0);
54 1.2.2.2 christos }
55 1.2.2.2 christos
56 1.2.2.2 christos ATF_TC(prompt_pid);
57 1.2.2.2 christos ATF_TC_HEAD(prompt_pid, tc)
58 1.2.2.2 christos {
59 1.2.2.2 christos
60 1.2.2.2 christos atf_tc_set_md_var(tc, "descr",
61 1.2.2.2 christos "Prompt length of the current dir and assert that it is sane");
62 1.2.2.2 christos }
63 1.2.2.2 christos
64 1.2.2.2 christos ATF_TC_BODY(prompt_pid, tc)
65 1.2.2.2 christos {
66 1.2.2.2 christos char buf[MAXPATHLEN];
67 1.2.2.2 christos char cwdbuf[MAXPATHLEN];
68 1.2.2.2 christos size_t len, prompted_len;
69 1.2.2.2 christos size_t i;
70 1.2.2.2 christos
71 1.2.2.2 christos pid_t t[] = {
72 1.2.2.2 christos -1,
73 1.2.2.2 christos getpid(),
74 1.2.2.2 christos 1 /* /sbin/init */
75 1.2.2.2 christos };
76 1.2.2.2 christos
77 1.2.2.2 christos for (i = 0; i < __arraycount(t); i++) {
78 1.2.2.2 christos len = 0;
79 1.2.2.2 christos ATF_REQUIRE_EQ(getproccwd(NULL, &len, t[i]), 0);
80 1.2.2.2 christos
81 1.2.2.2 christos prompted_len = len;
82 1.2.2.2 christos ATF_REQUIRE_EQ(getproccwd(buf, &len, t[i]), 0);
83 1.2.2.2 christos
84 1.2.2.2 christos ATF_REQUIRE_EQ(strlen(buf) + 1, prompted_len);
85 1.2.2.2 christos ATF_REQUIRE(strlen(buf) > 0);
86 1.2.2.2 christos
87 1.2.2.2 christos if (t[i] == -1 || t[i] == getpid()) {
88 1.2.2.2 christos getcwd(cwdbuf, MAXPATHLEN);
89 1.2.2.2 christos ATF_REQUIRE_EQ(strcmp(buf, cwdbuf), 0);
90 1.2.2.2 christos ATF_REQUIRE(strlen(buf) > strlen("/"));
91 1.2.2.2 christos } else if (t[i] == 1) {
92 1.2.2.2 christos ATF_REQUIRE_EQ(strcmp(buf, "/"), 0);
93 1.2.2.2 christos }
94 1.2.2.2 christos }
95 1.2.2.2 christos }
96 1.2.2.2 christos
97 1.2.2.2 christos ATF_TC(chroot);
98 1.2.2.2 christos ATF_TC_HEAD(chroot, tc)
99 1.2.2.2 christos {
100 1.2.2.2 christos
101 1.2.2.2 christos atf_tc_set_md_var(tc, "descr",
102 1.2.2.2 christos "prompt length of the current dir and assert that it is right");
103 1.2.2.2 christos
104 1.2.2.2 christos atf_tc_set_md_var(tc, "require.user", "root");
105 1.2.2.2 christos }
106 1.2.2.2 christos
107 1.2.2.2 christos #define ASSERT(x) do { if (!(x)) _exit(EXIT_FAILURE); } while (0)
108 1.2.2.2 christos
109 1.2.2.2 christos ATF_TC_BODY(chroot, tc)
110 1.2.2.2 christos {
111 1.2.2.2 christos char buf[MAXPATHLEN];
112 1.2.2.2 christos struct stat root_dir;
113 1.2.2.2 christos struct stat cur_dir;
114 1.2.2.2 christos size_t len;
115 1.2.2.2 christos pid_t child, wpid;
116 1.2.2.2 christos int status;
117 1.2.2.2 christos int rv;
118 1.2.2.2 christos
119 1.2.2.2 christos const pid_t pid_one = 1; /* /sbin/init */
120 1.2.2.2 christos
121 1.2.2.2 christos ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
122 1.2.2.2 christos
123 1.2.2.2 christos ATF_REQUIRE_EQ(stat(buf, &cur_dir), 0);
124 1.2.2.2 christos ATF_REQUIRE_EQ(stat("/", &root_dir), 0);
125 1.2.2.2 christos
126 1.2.2.2 christos if (cur_dir.st_ino == root_dir.st_ino)
127 1.2.2.2 christos atf_tc_skip("This test does not work in /");
128 1.2.2.2 christos
129 1.2.2.2 christos child = atf_utils_fork();
130 1.2.2.2 christos if (child == 0) {
131 1.2.2.2 christos len = 0;
132 1.2.2.2 christos
133 1.2.2.2 christos ASSERT(chroot(buf) == 0);
134 1.2.2.2 christos
135 1.2.2.2 christos errno = 0;
136 1.2.2.2 christos rv = getproccwd(buf, &len, pid_one);
137 1.2.2.2 christos ASSERT(rv == -1);
138 1.2.2.2 christos ASSERT(errno == ENOENT);
139 1.2.2.2 christos
140 1.2.2.2 christos _exit(EXIT_SUCCESS);
141 1.2.2.2 christos }
142 1.2.2.2 christos wpid = waitpid(child, &status, WEXITED);
143 1.2.2.2 christos ATF_REQUIRE_EQ(wpid, child);
144 1.2.2.2 christos ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS);
145 1.2.2.2 christos }
146 1.2.2.2 christos
147 1.2.2.2 christos ATF_TP_ADD_TCS(tp)
148 1.2.2.2 christos {
149 1.2.2.2 christos
150 1.2.2.2 christos ATF_TP_ADD_TC(tp, prompt_pid);
151 1.2.2.2 christos ATF_TP_ADD_TC(tp, chroot);
152 1.2.2.2 christos
153 1.2.2.2 christos return atf_no_error();
154 1.2.2.2 christos }
155