summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys/t_chroot.c
diff options
context:
space:
mode:
authorbluhm <>2019-11-19 19:57:04 +0000
committerbluhm <>2019-11-19 19:57:04 +0000
commit9185f840eda265016178aeb0dcdba964f8f6f3e2 (patch)
treeda100b3712514c566fe948116f7926ad7f725401 /src/regress/lib/libc/sys/t_chroot.c
parent6a6fe688152b422f3d65c970dad56e7d9d28b1ee (diff)
downloadopenbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.gz
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.bz2
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.zip
Import NetBSD system call regression tests. They were written with
ATF (Automated Testing Framework), so we use a small wrapper to map it to our bsd.regress.mk framework. Only half of the 80 NetBSD tests have been taken, the others need more work to adapt. Of them 34 syscall tests pass. Moritz Buhl ported the tests to OpenBSD.
Diffstat (limited to 'src/regress/lib/libc/sys/t_chroot.c')
-rw-r--r--src/regress/lib/libc/sys/t_chroot.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/src/regress/lib/libc/sys/t_chroot.c b/src/regress/lib/libc/sys/t_chroot.c
new file mode 100644
index 0000000000..1fbe392a88
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_chroot.c
@@ -0,0 +1,321 @@
1/* $OpenBSD: t_chroot.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $");
37
38#include <sys/wait.h>
39#include <sys/stat.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <pwd.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49
50ATF_TC(chroot_basic);
51ATF_TC_HEAD(chroot_basic, tc)
52{
53 atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)");
54 atf_tc_set_md_var(tc, "require.user", "root");
55}
56
57ATF_TC_BODY(chroot_basic, tc)
58{
59 char buf[PATH_MAX];
60 int fd, sta;
61 pid_t pid;
62
63 (void)memset(buf, '\0', sizeof(buf));
64 (void)getcwd(buf, sizeof(buf));
65 (void)strlcat(buf, "/dir", sizeof(buf));
66
67 ATF_REQUIRE(mkdir(buf, 0500) == 0);
68 ATF_REQUIRE(chdir(buf) == 0);
69
70 pid = fork();
71 ATF_REQUIRE(pid >= 0);
72
73 if (pid == 0) {
74
75 if (chroot(buf) != 0)
76 _exit(EXIT_FAILURE);
77
78 errno = 0;
79
80 if (chroot("/root") != -1)
81 _exit(EXIT_FAILURE);
82
83 if (errno != ENOENT)
84 _exit(EXIT_FAILURE);
85
86 fd = open("file", O_RDONLY | O_CREAT, 0600);
87
88 if (fd < 0)
89 _exit(EXIT_FAILURE);
90
91 if (close(fd) != 0)
92 _exit(EXIT_FAILURE);
93
94 _exit(EXIT_SUCCESS);
95 }
96
97 (void)wait(&sta);
98
99 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
100 atf_tc_fail("chroot(2) failed");
101
102 (void)chdir("/");
103 (void)strlcat(buf, "/file", sizeof(buf));
104
105 fd = open(buf, O_RDONLY);
106
107 if (fd < 0)
108 atf_tc_fail("chroot(2) did not change the root directory");
109
110 ATF_REQUIRE(close(fd) == 0);
111 ATF_REQUIRE(unlink(buf) == 0);
112}
113
114ATF_TC(chroot_err);
115ATF_TC_HEAD(chroot_err, tc)
116{
117 atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)");
118 atf_tc_set_md_var(tc, "require.user", "root");
119}
120
121ATF_TC_BODY(chroot_err, tc)
122{
123 char buf[PATH_MAX + 1];
124
125 (void)memset(buf, 'x', sizeof(buf));
126
127 errno = 0;
128 ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1);
129
130 errno = 0;
131 ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1);
132
133 errno = 0;
134 ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1);
135}
136
137ATF_TC(chroot_perm);
138ATF_TC_HEAD(chroot_perm, tc)
139{
140 atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)");
141 atf_tc_set_md_var(tc, "require.user", "unprivileged");
142}
143
144ATF_TC_BODY(chroot_perm, tc)
145{
146 static char buf[LINE_MAX];
147 pid_t pid;
148 int sta;
149
150 (void)memset(buf, '\0', sizeof(buf));
151 ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
152
153 pid = fork();
154 ATF_REQUIRE(pid >= 0);
155
156 if (pid == 0) {
157
158 errno = 0;
159
160 if (chroot(buf) != -1)
161 _exit(EXIT_FAILURE);
162
163 if (errno != EPERM)
164 _exit(EXIT_FAILURE);
165
166 _exit(EXIT_SUCCESS);
167 }
168
169 (void)wait(&sta);
170
171 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
172 atf_tc_fail("chroot(2) succeeded as unprivileged user");
173}
174
175ATF_TC(fchroot_basic);
176ATF_TC_HEAD(fchroot_basic, tc)
177{
178 atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)");
179 atf_tc_set_md_var(tc, "require.user", "root");
180}
181
182ATF_TC_BODY(fchroot_basic, tc)
183{
184 char buf[PATH_MAX];
185 int fd, sta;
186 pid_t pid;
187
188 (void)memset(buf, '\0', sizeof(buf));
189 (void)getcwd(buf, sizeof(buf));
190 (void)strlcat(buf, "/dir", sizeof(buf));
191
192 ATF_REQUIRE(mkdir(buf, 0500) == 0);
193 ATF_REQUIRE(chdir(buf) == 0);
194
195 fd = open(buf, O_RDONLY);
196 ATF_REQUIRE(fd >= 0);
197
198 pid = fork();
199 ATF_REQUIRE(pid >= 0);
200
201 if (pid == 0) {
202
203 if (fchroot(fd) != 0)
204 _exit(EXIT_FAILURE);
205
206 if (close(fd) != 0)
207 _exit(EXIT_FAILURE);
208
209 fd = open("file", O_RDONLY | O_CREAT, 0600);
210
211 if (fd < 0)
212 _exit(EXIT_FAILURE);
213
214 if (close(fd) != 0)
215 _exit(EXIT_FAILURE);
216
217 _exit(EXIT_SUCCESS);
218 }
219
220 (void)wait(&sta);
221
222 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
223 atf_tc_fail("fchroot(2) failed");
224
225 (void)chdir("/");
226 (void)strlcat(buf, "/file", sizeof(buf));
227
228 fd = open(buf, O_RDONLY);
229
230 if (fd < 0)
231 atf_tc_fail("fchroot(2) did not change the root directory");
232
233 ATF_REQUIRE(close(fd) == 0);
234 ATF_REQUIRE(unlink(buf) == 0);
235}
236
237ATF_TC(fchroot_err);
238ATF_TC_HEAD(fchroot_err, tc)
239{
240 atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)");
241 atf_tc_set_md_var(tc, "require.user", "root");
242}
243
244ATF_TC_BODY(fchroot_err, tc)
245{
246 int fd;
247
248 fd = open("/etc/passwd", O_RDONLY);
249 ATF_REQUIRE(fd >= 0);
250
251 errno = 0;
252 ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1);
253
254 errno = 0;
255 ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1);
256
257 ATF_REQUIRE(close(fd) == 0);
258}
259
260ATF_TC(fchroot_perm);
261ATF_TC_HEAD(fchroot_perm, tc)
262{
263 atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)");
264 atf_tc_set_md_var(tc, "require.user", "root");
265}
266
267ATF_TC_BODY(fchroot_perm, tc)
268{
269 static char buf[LINE_MAX];
270 struct passwd *pw;
271 int fd, sta;
272 pid_t pid;
273
274 (void)memset(buf, '\0', sizeof(buf));
275 ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
276
277 pw = getpwnam("nobody");
278 fd = open(buf, O_RDONLY);
279
280 ATF_REQUIRE(fd >= 0);
281 ATF_REQUIRE(pw != NULL);
282
283 pid = fork();
284 ATF_REQUIRE(pid >= 0);
285
286 if (pid == 0) {
287
288 (void)setuid(pw->pw_uid);
289
290 errno = 0;
291
292 if (fchroot(fd) != -1)
293 _exit(EXIT_FAILURE);
294
295 if (errno != EPERM)
296 _exit(EXIT_FAILURE);
297
298 _exit(EXIT_SUCCESS);
299 }
300
301 (void)wait(&sta);
302
303 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
304 atf_tc_fail("fchroot(2) succeeded as unprivileged user");
305}
306
307ATF_TP_ADD_TCS(tp)
308{
309
310 ATF_TP_ADD_TC(tp, chroot_basic);
311 ATF_TP_ADD_TC(tp, chroot_err);
312 ATF_TP_ADD_TC(tp, chroot_perm);
313/*
314 * Not available on OpenBSD
315 * ATF_TP_ADD_TC(tp, fchroot_basic);
316 * ATF_TP_ADD_TC(tp, fchroot_err);
317 * ATF_TP_ADD_TC(tp, fchroot_perm);
318 */
319
320 return atf_no_error();
321}