]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/file/path_test.c
zfs: merge openzfs/zfs@229b9f4ed
[FreeBSD/FreeBSD.git] / tests / sys / file / path_test.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 The FreeBSD Foundation
5  *
6  * This software was developed by Mark Johnston under sponsorship from
7  * the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 /*
32  * Basic regression tests for handling of O_PATH descriptors.
33  */
34
35 #include <sys/param.h>
36 #include <sys/capsicum.h>
37 #include <sys/event.h>
38 #include <sys/ioctl.h>
39 #include <sys/memrange.h>
40 #include <sys/mman.h>
41 #include <sys/ptrace.h>
42 #include <sys/socket.h>
43 #include <sys/stat.h>
44 #include <sys/time.h>
45 #include <sys/uio.h>
46 #include <sys/un.h>
47 #include <sys/wait.h>
48
49 #include <aio.h>
50 #include <dirent.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #include <poll.h>
54 #include <signal.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <unistd.h>
58
59 #include <atf-c.h>
60
61 #define FMT_ERR(s)              s ": %s", strerror(errno)
62
63 #define CHECKED_CLOSE(fd)       \
64         ATF_REQUIRE_MSG(close(fd) == 0, FMT_ERR("close"))
65
66 /* Create a temporary regular file containing some data. */
67 static void
68 mktfile(char path[PATH_MAX], const char *template)
69 {
70         char buf[BUFSIZ];
71         int fd;
72
73         snprintf(path, PATH_MAX, "%s", template);
74         fd = mkstemp(path);
75         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("mkstemp"));
76         memset(buf, 0, sizeof(buf));
77         ATF_REQUIRE_MSG(write(fd, buf, sizeof(buf)) == sizeof(buf),
78             FMT_ERR("write"));
79         CHECKED_CLOSE(fd);
80 }
81
82 /* Make a temporary directory. */
83 static void
84 mktdir(char path[PATH_MAX], const char *template)
85 {
86         snprintf(path, PATH_MAX, "%s", template);
87         ATF_REQUIRE_MSG(mkdtemp(path) == path, FMT_ERR("mkdtemp"));
88 }
89
90 /* Wait for a child process to exit with status 0. */
91 static void
92 waitchild(pid_t child, int exstatus)
93 {
94         int error, status;
95
96         error = waitpid(child, &status, 0);
97         ATF_REQUIRE_MSG(error != -1, FMT_ERR("waitpid"));
98         ATF_REQUIRE_MSG(WIFEXITED(status), "child exited abnormally, status %d",
99             status);
100         ATF_REQUIRE_MSG(WEXITSTATUS(status) == exstatus,
101             "child exit status is %d, expected %d",
102             WEXITSTATUS(status), exstatus);
103 }
104
105 ATF_TC_WITHOUT_HEAD(path_access);
106 ATF_TC_BODY(path_access, tc)
107 {
108         char path[PATH_MAX];
109         struct stat sb;
110         struct timespec ts[2];
111         struct timeval tv[2];
112         int pathfd;
113
114         mktfile(path, "path_access.XXXXXX");
115
116         pathfd = open(path, O_PATH);
117         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
118
119         ATF_REQUIRE_ERRNO(EBADF, fchmod(pathfd, 0666) == -1);
120         ATF_REQUIRE_ERRNO(EBADF, fchown(pathfd, getuid(), getgid()) == -1);
121         ATF_REQUIRE_ERRNO(EBADF, fchflags(pathfd, UF_NODUMP) == -1);
122         memset(tv, 0, sizeof(tv));
123         ATF_REQUIRE_ERRNO(EBADF, futimes(pathfd, tv) == -1);
124         memset(ts, 0, sizeof(ts));
125         ATF_REQUIRE_ERRNO(EBADF, futimens(pathfd, ts) == -1);
126
127         /* fpathconf(2) and fstat(2) are permitted. */
128         ATF_REQUIRE_MSG(fstat(pathfd, &sb) == 0, FMT_ERR("fstat"));
129         ATF_REQUIRE_MSG(fpathconf(pathfd, _PC_LINK_MAX) != -1,
130             FMT_ERR("fpathconf"));
131
132         CHECKED_CLOSE(pathfd);
133 }
134
135 /* Basic tests to verify that AIO operations fail. */
136 ATF_TC_WITHOUT_HEAD(path_aio);
137 ATF_TC_BODY(path_aio, tc)
138 {
139         struct aiocb aio;
140         char buf[BUFSIZ], path[PATH_MAX];
141         int pathfd;
142
143         mktfile(path, "path_aio.XXXXXX");
144
145         pathfd = open(path, O_PATH);
146         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
147
148         memset(&aio, 0, sizeof(aio));
149         aio.aio_buf = buf;
150         aio.aio_nbytes = sizeof(buf);
151         aio.aio_fildes = pathfd;
152         aio.aio_offset = 0;
153
154         ATF_REQUIRE_ERRNO(EBADF, aio_read(&aio) == -1);
155         ATF_REQUIRE_ERRNO(EBADF, aio_write(&aio) == -1);
156         ATF_REQUIRE_ERRNO(EBADF, aio_fsync(O_SYNC, &aio) == -1);
157         ATF_REQUIRE_ERRNO(EBADF, aio_fsync(O_DSYNC, &aio) == -1);
158
159         CHECKED_CLOSE(pathfd);
160 }
161
162 /* Basic tests to verify that Capsicum restrictions apply to path fds. */
163 ATF_TC_WITHOUT_HEAD(path_capsicum);
164 ATF_TC_BODY(path_capsicum, tc)
165 {
166         char path[PATH_MAX];
167         cap_rights_t rights;
168         int truefd;
169         pid_t child;
170
171         mktfile(path, "path_capsicum.XXXXXX");
172
173         /* Make sure that filesystem namespace restrictions apply to O_PATH. */
174         child = fork();
175         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
176         if (child == 0) {
177                 if (cap_enter() != 0)
178                         _exit(1);
179                 if (open(path, O_PATH) >= 0)
180                         _exit(2);
181                 if (errno != ECAPMODE)
182                         _exit(3);
183                 if (open("/usr/bin/true", O_PATH | O_EXEC) >= 0)
184                         _exit(4);
185                 if (errno != ECAPMODE)
186                         _exit(5);
187                 _exit(0);
188         }
189         waitchild(child, 0);
190
191         /* Make sure that CAP_FEXECVE is required. */
192         child = fork();
193         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
194         if (child == 0) {
195                 truefd = open("/usr/bin/true", O_PATH | O_EXEC);
196                 if (truefd < 0)
197                         _exit(1);
198                 cap_rights_init(&rights);
199                 if (cap_rights_limit(truefd, &rights) != 0)
200                         _exit(2);
201                 (void)fexecve(truefd,
202                     (char * const[]){__DECONST(char *, "/usr/bin/true"), NULL},
203                     NULL);
204                 if (errno != ENOTCAPABLE)
205                         _exit(3);
206                 _exit(4);
207         }
208         waitchild(child, 4);
209 }
210
211 /*
212  * Check that a pathfd can be converted to a regular fd using openat() in
213  * capability mode, but that rights on the pathfd are respected.
214  */
215 ATF_TC_WITHOUT_HEAD(path_capsicum_empty);
216 ATF_TC_BODY(path_capsicum_empty, tc)
217 {
218         char path[PATH_MAX];
219         cap_rights_t rights;
220         int dfd, fd, pathfd, pathdfd;
221
222         mktfile(path, "path_capsicum.XXXXXX");
223
224         pathdfd = open(".", O_PATH);
225         ATF_REQUIRE_MSG(pathdfd >= 0, FMT_ERR("open"));
226         pathfd = open(path, O_PATH);
227         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
228
229         ATF_REQUIRE(cap_enter() == 0);
230
231         dfd = openat(pathdfd, "", O_DIRECTORY | O_EMPTY_PATH);
232         ATF_REQUIRE(dfd >= 0);
233         CHECKED_CLOSE(dfd);
234
235         /*
236          * CAP_READ and CAP_LOOKUP should be sufficient to open a directory.
237          */
238         cap_rights_init(&rights, CAP_READ | CAP_LOOKUP);
239         ATF_REQUIRE(cap_rights_limit(pathdfd, &rights) == 0);
240         dfd = openat(pathdfd, "", O_DIRECTORY | O_EMPTY_PATH);
241         ATF_REQUIRE(dfd >= 0);
242         CHECKED_CLOSE(dfd);
243
244         /*
245          * ... CAP_READ on its own is not.
246          */
247         cap_rights_init(&rights, CAP_READ);
248         ATF_REQUIRE(cap_rights_limit(pathdfd, &rights) == 0);
249         dfd = openat(pathdfd, "", O_DIRECTORY | O_EMPTY_PATH);
250         ATF_REQUIRE_ERRNO(ENOTCAPABLE, dfd == -1);
251
252         /*
253          * Now try with a regular file.
254          */
255         fd = openat(pathfd, "", O_RDWR | O_EMPTY_PATH);
256         ATF_REQUIRE(fd >= 0);
257         CHECKED_CLOSE(fd);
258
259         cap_rights_init(&rights, CAP_READ | CAP_LOOKUP | CAP_WRITE);
260         ATF_REQUIRE(cap_rights_limit(pathfd, &rights) == 0);
261         fd = openat(pathfd, "", O_RDWR | O_EMPTY_PATH | O_APPEND);
262         ATF_REQUIRE(fd >= 0);
263         CHECKED_CLOSE(fd);
264
265         /*
266          * CAP_SEEK is needed to open a file for writing without O_APPEND.
267          */
268         cap_rights_init(&rights, CAP_READ | CAP_LOOKUP | CAP_WRITE);
269         ATF_REQUIRE(cap_rights_limit(pathfd, &rights) == 0);
270         fd = openat(pathfd, "", O_RDWR | O_EMPTY_PATH);
271         ATF_REQUIRE_ERRNO(ENOTCAPABLE, fd == -1);
272
273         /*
274          * CAP_LOOKUP isn't sufficient to open a file for reading.
275          */
276         cap_rights_init(&rights, CAP_LOOKUP);
277         ATF_REQUIRE(cap_rights_limit(pathfd, &rights) == 0);
278         fd = openat(pathfd, "", O_RDONLY | O_EMPTY_PATH);
279         ATF_REQUIRE_ERRNO(ENOTCAPABLE, fd == -1);
280
281         CHECKED_CLOSE(pathfd);
282         CHECKED_CLOSE(pathdfd);
283 }
284
285 /* Make sure that ptrace(PT_COREDUMP) cannot be used to write to a path fd. */
286 ATF_TC_WITHOUT_HEAD(path_coredump);
287 ATF_TC_BODY(path_coredump, tc)
288 {
289         char path[PATH_MAX];
290         struct ptrace_coredump pc;
291         int error, pathfd, status;
292         pid_t child;
293
294         mktdir(path, "path_coredump.XXXXXX");
295
296         child = fork();
297         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
298         if (child == 0) {
299                 while (true)
300                         (void)sleep(1);
301         }
302
303         pathfd = open(path, O_PATH);
304         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
305
306         error = ptrace(PT_ATTACH, child, 0, 0);
307         ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
308         error = waitpid(child, &status, 0);
309         ATF_REQUIRE_MSG(error != -1, FMT_ERR("waitpid"));
310         ATF_REQUIRE_MSG(WIFSTOPPED(status), "unexpected status %d", status);
311
312         pc.pc_fd = pathfd;
313         pc.pc_flags = 0;
314         pc.pc_limit = 0;
315         error = ptrace(PT_COREDUMP, child, (void *)&pc, sizeof(pc));
316         ATF_REQUIRE_ERRNO(EBADF, error == -1);
317
318         error = ptrace(PT_DETACH, child, 0, 0);
319         ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
320
321         ATF_REQUIRE_MSG(kill(child, SIGKILL) == 0, FMT_ERR("kill"));
322
323         CHECKED_CLOSE(pathfd);
324 }
325
326 /* Verify operations on directory path descriptors. */
327 ATF_TC_WITHOUT_HEAD(path_directory);
328 ATF_TC_BODY(path_directory, tc)
329 {
330         struct dirent de;
331         struct stat sb;
332         char path[PATH_MAX];
333         int fd, pathfd;
334
335         mktdir(path, "path_directory.XXXXXX");
336
337         pathfd = open(path, O_PATH | O_DIRECTORY);
338         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
339
340         /* Should not be possible to list directory entries. */
341         ATF_REQUIRE_ERRNO(EBADF,
342             getdirentries(pathfd, (char *)&de, sizeof(de), NULL) == -1);
343
344         /* It should be possible to create files under pathfd. */
345         fd = openat(pathfd, "test", O_RDWR | O_CREAT, 0600);
346         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
347         ATF_REQUIRE_MSG(fstatat(pathfd, "test", &sb, 0) == 0,
348             FMT_ERR("fstatat"));
349         CHECKED_CLOSE(fd);
350
351         /* ... but doing so requires write access. */
352         if (geteuid() != 0) {
353                 ATF_REQUIRE_ERRNO(EBADF, fchmod(pathfd, 0500) == -1);
354                 ATF_REQUIRE_MSG(chmod(path, 0500) == 0, FMT_ERR("chmod"));
355                 ATF_REQUIRE_ERRNO(EACCES,
356                     openat(pathfd, "test2", O_RDWR | O_CREAT, 0600) < 0);
357         }
358
359         /* fchdir(2) is permitted. */
360         ATF_REQUIRE_MSG(fchdir(pathfd) == 0, FMT_ERR("fchdir"));
361
362         CHECKED_CLOSE(pathfd);
363 }
364
365 /* Verify access permission checking for a directory path fd. */
366 ATF_TC_WITH_CLEANUP(path_directory_not_root);
367 ATF_TC_HEAD(path_directory_not_root, tc)
368 {
369         atf_tc_set_md_var(tc, "require.user", "unprivileged");
370 }
371 ATF_TC_BODY(path_directory_not_root, tc)
372 {
373         char path[PATH_MAX];
374         int pathfd;
375
376         mktdir(path, "path_directory.XXXXXX");
377
378         pathfd = open(path, O_PATH | O_DIRECTORY);
379         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
380
381         ATF_REQUIRE_ERRNO(EBADF, fchmod(pathfd, 0500) == -1);
382         ATF_REQUIRE_MSG(chmod(path, 0500) == 0, FMT_ERR("chmod"));
383         ATF_REQUIRE_ERRNO(EACCES,
384             openat(pathfd, "test2", O_RDWR | O_CREAT, 0600) < 0);
385
386         CHECKED_CLOSE(pathfd);
387 }
388 ATF_TC_CLEANUP(path_directory_not_root, tc)
389 {
390 }
391
392 /* Validate system calls that handle AT_EMPTY_PATH. */
393 ATF_TC_WITHOUT_HEAD(path_empty);
394 ATF_TC_BODY(path_empty, tc)
395 {
396         char path[PATH_MAX];
397         struct timespec ts[2];
398         struct stat sb;
399         int pathfd;
400
401         mktfile(path, "path_empty.XXXXXX");
402
403         pathfd = open(path, O_PATH);
404         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
405
406         /* Various *at operations should work on path fds. */
407         ATF_REQUIRE_MSG(faccessat(pathfd, "", F_OK, AT_EMPTY_PATH) == 0,
408             FMT_ERR("faccessat"));
409         ATF_REQUIRE_MSG(chflagsat(pathfd, "", UF_NODUMP, AT_EMPTY_PATH) == 0,
410             FMT_ERR("chflagsat"));
411         ATF_REQUIRE_MSG(fchmodat(pathfd, "", 0600, AT_EMPTY_PATH) == 0,
412             FMT_ERR("fchmodat"));
413         ATF_REQUIRE_MSG(fchownat(pathfd, "", getuid(), getgid(),
414             AT_EMPTY_PATH) == 0, FMT_ERR("fchownat"));
415         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
416             FMT_ERR("fstatat"));
417         ATF_REQUIRE_MSG(sb.st_size == BUFSIZ,
418             "unexpected size %ju", (uintmax_t)sb.st_size);
419         memset(ts, 0, sizeof(ts));
420         ATF_REQUIRE_MSG(utimensat(pathfd, "", ts, AT_EMPTY_PATH) == 0,
421             FMT_ERR("utimensat"));
422
423         CHECKED_CLOSE(pathfd);
424 }
425
426 /* Verify that various operations on a path fd have access checks. */
427 ATF_TC_WITH_CLEANUP(path_empty_not_root);
428 ATF_TC_HEAD(path_empty_not_root, tc)
429 {
430         atf_tc_set_md_var(tc, "require.user", "unprivileged");
431 }
432 ATF_TC_BODY(path_empty_not_root, tc)
433 {
434         int pathfd;
435
436         pathfd = open("/dev/null", O_PATH);
437         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
438
439         ATF_REQUIRE_ERRNO(EPERM,
440             chflagsat(pathfd, "", UF_NODUMP, AT_EMPTY_PATH) == -1);
441         ATF_REQUIRE_ERRNO(EPERM,
442             fchownat(pathfd, "", getuid(), getgid(), AT_EMPTY_PATH) == -1);
443         ATF_REQUIRE_ERRNO(EPERM,
444             fchmodat(pathfd, "", 0600, AT_EMPTY_PATH) == -1);
445         ATF_REQUIRE_ERRNO(EPERM,
446             linkat(pathfd, "", AT_FDCWD, "test", AT_EMPTY_PATH) == -1);
447
448         CHECKED_CLOSE(pathfd);
449 }
450 ATF_TC_CLEANUP(path_empty_not_root, tc)
451 {
452 }
453
454 /* Test linkat(2) with AT_EMPTY_PATH, which requires privileges. */
455 ATF_TC_WITH_CLEANUP(path_empty_root);
456 ATF_TC_HEAD(path_empty_root, tc)
457 {
458         atf_tc_set_md_var(tc, "require.user", "root");
459 }
460 ATF_TC_BODY(path_empty_root, tc)
461 {
462         char path[PATH_MAX];
463         struct stat sb, sb2;
464         int pathfd;
465
466         mktfile(path, "path_empty_root.XXXXXX");
467
468         pathfd = open(path, O_PATH);
469         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
470         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
471             FMT_ERR("fstatat"));
472
473         ATF_REQUIRE_MSG(linkat(pathfd, "", AT_FDCWD, "test", AT_EMPTY_PATH) ==
474             0, FMT_ERR("linkat"));
475         ATF_REQUIRE_MSG(fstatat(AT_FDCWD, "test", &sb2, 0) == 0,
476             FMT_ERR("fstatat"));
477         ATF_REQUIRE_MSG(sb.st_dev == sb2.st_dev, "st_dev mismatch");
478         ATF_REQUIRE_MSG(sb.st_ino == sb2.st_ino, "st_ino mismatch");
479
480         CHECKED_CLOSE(pathfd);
481
482 }
483 ATF_TC_CLEANUP(path_empty_root, tc)
484 {
485 }
486
487 /* poll(2) never returns an event for path fds, but kevent(2) does. */
488 ATF_TC_WITHOUT_HEAD(path_event);
489 ATF_TC_BODY(path_event, tc)
490 {
491         char buf[BUFSIZ], path[PATH_MAX];
492         struct kevent ev;
493         struct pollfd pollfd;
494         int kq, pathfd;
495
496         mktfile(path, "path_event.XXXXXX");
497
498         pathfd = open(path, O_PATH);
499         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
500
501         /* poll(2) should return POLLNVAL. */
502         pollfd.fd = pathfd;
503         pollfd.events = POLLIN;
504         pollfd.revents = 0;
505         ATF_REQUIRE_MSG(poll(&pollfd, 1, 0) == 1, FMT_ERR("poll"));
506         ATF_REQUIRE_MSG(pollfd.revents == POLLNVAL, "unexpected revents %x",
507             pollfd.revents);
508         pollfd.events = POLLOUT;
509         pollfd.revents = 0;
510         ATF_REQUIRE_MSG(poll(&pollfd, 1, 0) == 1, FMT_ERR("poll"));
511         ATF_REQUIRE_MSG(pollfd.revents == POLLNVAL, "unexpected revents %x",
512             pollfd.revents);
513
514         /* Try to get a EVFILT_READ event through a path fd. */
515         kq = kqueue();
516         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
517         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
518         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
519             FMT_ERR("kevent"));
520         ATF_REQUIRE_MSG(kevent(kq, NULL, 0, &ev, 1, NULL) == 1,
521             FMT_ERR("kevent"));
522         ATF_REQUIRE_MSG((ev.flags & EV_ERROR) == 0, "EV_ERROR is set");
523         ATF_REQUIRE_MSG(ev.data == sizeof(buf),
524             "data is %jd", (intmax_t)ev.data);
525         EV_SET(&ev, pathfd, EVFILT_READ, EV_DELETE, 0, 0, 0);
526         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
527             FMT_ERR("kevent"));
528
529         /* Try to get a EVFILT_VNODE/NOTE_DELETE event through a path fd. */
530         EV_SET(&ev, pathfd, EVFILT_VNODE, EV_ADD | EV_ENABLE, NOTE_DELETE, 0,
531             0);
532         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
533             FMT_ERR("kevent"));
534         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
535             FMT_ERR("funlinkat"));
536         ATF_REQUIRE_MSG(kevent(kq, NULL, 0, &ev, 1, NULL) == 1,
537             FMT_ERR("kevent"));
538         ATF_REQUIRE_MSG(ev.fflags == NOTE_DELETE,
539             "unexpected fflags %#x", ev.fflags);
540         EV_SET(&ev, pathfd, EVFILT_VNODE, EV_DELETE, 0, 0, 0);
541         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
542             FMT_ERR("kevent"));
543
544         CHECKED_CLOSE(kq);
545         CHECKED_CLOSE(pathfd);
546 }
547
548 /* Check various fcntl(2) operations on a path desriptor. */
549 ATF_TC_WITHOUT_HEAD(path_fcntl);
550 ATF_TC_BODY(path_fcntl, tc)
551 {
552         char path[PATH_MAX];
553         int flags, pathfd, pathfd2;
554
555         mktfile(path, "path_fcntl.XXXXXX");
556
557         pathfd = open(path, O_PATH);
558         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
559
560         /* O_PATH should appear in the fd flags. */
561         flags = fcntl(pathfd, F_GETFL);
562         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
563         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
564
565         ATF_REQUIRE_ERRNO(EBADF,
566             fcntl(pathfd, F_SETFL, flags & ~O_PATH));
567         ATF_REQUIRE_ERRNO(EBADF,
568             fcntl(pathfd, F_SETFL, flags | O_APPEND));
569
570         /* A dup'ed O_PATH fd had better have O_PATH set too. */
571         pathfd2 = fcntl(pathfd, F_DUPFD, 0);
572         ATF_REQUIRE_MSG(pathfd2 >= 0, FMT_ERR("fcntl"));
573         flags = fcntl(pathfd2, F_GETFL);
574         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
575         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
576         CHECKED_CLOSE(pathfd2);
577
578         /* Double check with dup(2). */
579         pathfd2 = dup(pathfd);
580         ATF_REQUIRE_MSG(pathfd2 >= 0, FMT_ERR("dup"));
581         flags = fcntl(pathfd2, F_GETFL);
582         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
583         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
584         CHECKED_CLOSE(pathfd2);
585
586         /* It should be possible to set O_CLOEXEC. */
587         ATF_REQUIRE_MSG(fcntl(pathfd, F_SETFD, FD_CLOEXEC) == 0,
588             FMT_ERR("fcntl"));
589         ATF_REQUIRE_MSG(fcntl(pathfd, F_GETFD) == FD_CLOEXEC,
590             FMT_ERR("fcntl"));
591
592         CHECKED_CLOSE(pathfd);
593 }
594
595 /* Verify that we can execute a file opened with O_PATH. */
596 ATF_TC_WITHOUT_HEAD(path_fexecve);
597 ATF_TC_BODY(path_fexecve, tc)
598 {
599         char path[PATH_MAX];
600         pid_t child;
601         int fd, pathfd;
602
603         child = fork();
604         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
605         if (child == 0) {
606                 pathfd = open("/usr/bin/true", O_PATH | O_EXEC);
607                 if (pathfd < 0)
608                         _exit(1);
609                 fexecve(pathfd,
610                     (char * const[]){__DECONST(char *, "/usr/bin/true"), NULL},
611                     NULL);
612                 _exit(2);
613         }
614         waitchild(child, 0);
615
616         /*
617          * Also verify that access permissions are checked when opening with
618          * O_PATH.
619          */
620         snprintf(path, sizeof(path), "path_fexecve.XXXXXX");
621         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
622
623         fd = open(path, O_CREAT | O_RDONLY, 0600);
624         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
625
626         pathfd = open(path, O_PATH | O_EXEC);
627         ATF_REQUIRE_ERRNO(EACCES, pathfd < 0);
628 }
629
630 /* Make sure that O_PATH restrictions apply to named pipes as well. */
631 ATF_TC_WITHOUT_HEAD(path_fifo);
632 ATF_TC_BODY(path_fifo, tc)
633 {
634         char path[PATH_MAX], buf[BUFSIZ];
635         struct kevent ev;
636         int kq, pathfd;
637
638         snprintf(path, sizeof(path), "path_fifo.XXXXXX");
639         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
640
641         ATF_REQUIRE_MSG(mkfifo(path, 0666) == 0, FMT_ERR("mkfifo"));
642
643         pathfd = open(path, O_PATH);
644         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
645         memset(buf, 0, sizeof(buf));
646         ATF_REQUIRE_ERRNO(EBADF, write(pathfd, buf, sizeof(buf)));
647         ATF_REQUIRE_ERRNO(EBADF, read(pathfd, buf, sizeof(buf)));
648
649         kq = kqueue();
650         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
651         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
652         ATF_REQUIRE_ERRNO(EBADF, kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
653
654         CHECKED_CLOSE(pathfd);
655 }
656
657 /* Files may be unlinked using a path fd. */
658 ATF_TC_WITHOUT_HEAD(path_funlinkat);
659 ATF_TC_BODY(path_funlinkat, tc)
660 {
661         char path[PATH_MAX];
662         struct stat sb;
663         int pathfd;
664
665         mktfile(path, "path_rights.XXXXXX");
666
667         pathfd = open(path, O_PATH);
668         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
669
670         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
671             FMT_ERR("funlinkat"));
672         ATF_REQUIRE_ERRNO(ENOENT, stat(path, &sb) == -1);
673
674         CHECKED_CLOSE(pathfd);
675 }
676
677 /* Verify that various I/O operations fail on an O_PATH descriptor. */
678 ATF_TC_WITHOUT_HEAD(path_io);
679 ATF_TC_BODY(path_io, tc)
680 {
681         char path[PATH_MAX], path2[PATH_MAX];
682         char buf[BUFSIZ];
683         struct iovec iov;
684         size_t page_size;
685         int error, fd, pathfd, sd[2];
686
687         /* It shouldn't be possible to create new files with O_PATH. */
688         snprintf(path, sizeof(path), "path_io.XXXXXX");
689         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
690         ATF_REQUIRE_ERRNO(ENOENT, open(path, O_PATH | O_CREAT, 0600) < 0);
691
692         /* Create a non-empty file for use in the rest of the tests. */
693         mktfile(path, "path_io.XXXXXX");
694
695         pathfd = open(path, O_PATH);
696         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
697
698         /* Make sure that basic I/O operations aren't possible. */
699         iov.iov_base = path;
700         iov.iov_len = strlen(path);
701         ATF_REQUIRE_ERRNO(EBADF,
702             write(pathfd, iov.iov_base, iov.iov_len) == -1);
703         ATF_REQUIRE_ERRNO(EBADF,
704             pwrite(pathfd, iov.iov_base, iov.iov_len, 0) == -1);
705         ATF_REQUIRE_ERRNO(EBADF,
706             writev(pathfd, &iov, 1) == -1);
707         ATF_REQUIRE_ERRNO(EBADF,
708             pwritev(pathfd, &iov, 1, 0) == -1);
709         ATF_REQUIRE_ERRNO(EBADF,
710             read(pathfd, path, 1) == -1);
711         ATF_REQUIRE_ERRNO(EBADF,
712             pread(pathfd, path, 1, 0) == -1);
713         ATF_REQUIRE_ERRNO(EBADF,
714             readv(pathfd, &iov, 1) == -1);
715         ATF_REQUIRE_ERRNO(EBADF,
716             preadv(pathfd, &iov, 1, 0) == -1);
717
718         /* copy_file_range() should not be permitted. */
719         mktfile(path2, "path_io.XXXXXX");
720         fd = open(path2, O_RDWR);
721         ATF_REQUIRE_ERRNO(EBADF,
722             copy_file_range(fd, NULL, pathfd, NULL, sizeof(buf), 0) == -1);
723         ATF_REQUIRE_ERRNO(EBADF,
724             copy_file_range(pathfd, NULL, fd, NULL, sizeof(buf), 0) == -1);
725         CHECKED_CLOSE(fd);
726
727         /* sendfile() should not be permitted. */
728         ATF_REQUIRE_MSG(socketpair(PF_LOCAL, SOCK_STREAM, 0, sd) == 0,
729             FMT_ERR("socketpair"));
730         ATF_REQUIRE_ERRNO(EBADF,
731             sendfile(pathfd, sd[0], 0, 0, NULL, NULL, 0));
732         CHECKED_CLOSE(sd[0]);
733         CHECKED_CLOSE(sd[1]);
734
735         /* No seeking. */
736         ATF_REQUIRE_ERRNO(ESPIPE,
737             lseek(pathfd, 0, SEEK_SET) == -1);
738
739         /* No operations on the file extent. */
740         ATF_REQUIRE_ERRNO(EINVAL,
741             ftruncate(pathfd, 0) == -1);
742         error = posix_fallocate(pathfd, 0, sizeof(buf) * 2);
743         ATF_REQUIRE_MSG(error == ESPIPE, "posix_fallocate() returned %d", error);
744         error = posix_fadvise(pathfd, 0, sizeof(buf), POSIX_FADV_NORMAL);
745         ATF_REQUIRE_MSG(error == ESPIPE, "posix_fadvise() returned %d", error);
746
747         /* mmap() is not allowed. */
748         page_size = getpagesize();
749         ATF_REQUIRE_ERRNO(ENODEV,
750             mmap(NULL, page_size, PROT_READ, MAP_SHARED, pathfd, 0) ==
751             MAP_FAILED);
752         ATF_REQUIRE_ERRNO(ENODEV,
753             mmap(NULL, page_size, PROT_NONE, MAP_SHARED, pathfd, 0) ==
754             MAP_FAILED);
755         ATF_REQUIRE_ERRNO(ENODEV,
756             mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, pathfd, 0) ==
757             MAP_FAILED);
758
759         /* No fsync() or fdatasync(). */
760         ATF_REQUIRE_ERRNO(EBADF, fsync(pathfd) == -1);
761         ATF_REQUIRE_ERRNO(EBADF, fdatasync(pathfd) == -1);
762
763         CHECKED_CLOSE(pathfd);
764 }
765
766 /* ioctl(2) is not permitted on path fds. */
767 ATF_TC_WITHOUT_HEAD(path_ioctl);
768 ATF_TC_BODY(path_ioctl, tc)
769 {
770         char path[PATH_MAX];
771         struct mem_extract me;
772         int pathfd, val;
773
774         mktfile(path, "path_ioctl.XXXXXX");
775
776         /* Standard file descriptor ioctls should fail. */
777         pathfd = open(path, O_PATH);
778         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
779
780         val = 0;
781         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONBIO, &val) == -1);
782         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONREAD, &val) == -1);
783         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONWRITE, &val) == -1);
784         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONSPACE, &val) == -1);
785
786         CHECKED_CLOSE(pathfd);
787
788         /* Device ioctls should fail. */
789         pathfd = open("/dev/mem", O_PATH);
790         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
791
792         me.me_vaddr = (uintptr_t)&me;
793         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, MEM_EXTRACT_PADDR, &me) == -1);
794
795         CHECKED_CLOSE(pathfd);
796 }
797
798 ATF_TC_WITHOUT_HEAD(path_lock);
799 ATF_TC_BODY(path_lock, tc)
800 {
801         char buf[BUFSIZ], path[PATH_MAX];
802         struct flock flk;
803         int fd, pathfd;
804
805         snprintf(path, sizeof(path), "path_rights.XXXXXX");
806         fd = mkostemp(path, O_SHLOCK);
807         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("mkostemp"));
808         memset(buf, 0, sizeof(buf));
809         ATF_REQUIRE_MSG(write(fd, buf, sizeof(buf)) == sizeof(buf),
810             FMT_ERR("write()"));
811
812         /* Verify that O_EXLOCK is ignored when combined with O_PATH. */
813         pathfd = open(path, O_PATH | O_EXLOCK);
814         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
815
816         CHECKED_CLOSE(fd);
817
818         /* flock(2) is prohibited. */
819         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_SH) == -1);
820         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_EX) == -1);
821         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_SH | LOCK_NB) == -1);
822         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_EX | LOCK_NB) == -1);
823         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_UN) == -1);
824
825         /* fcntl(2) file locks are prohibited. */
826         memset(&flk, 0, sizeof(flk));
827         flk.l_whence = SEEK_CUR;
828         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_GETLK, &flk) == -1);
829         flk.l_type = F_RDLCK;
830         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLK, &flk) == -1);
831         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLKW, &flk) == -1);
832         flk.l_type = F_WRLCK;
833         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLK, &flk) == -1);
834         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLKW, &flk) == -1);
835
836         CHECKED_CLOSE(pathfd);
837 }
838
839 /*
840  * Verify fstatat(AT_EMPTY_PATH) on non-regular dirfd.
841  * Verify that fstatat(AT_EMPTY_PATH) on NULL path returns EFAULT.
842  */
843 ATF_TC_WITHOUT_HEAD(path_pipe_fstatat);
844 ATF_TC_BODY(path_pipe_fstatat, tc)
845 {
846         struct stat sb;
847         int fd[2];
848
849         ATF_REQUIRE_MSG(pipe(fd) == 0, FMT_ERR("pipe"));
850         ATF_REQUIRE_MSG(fstatat(fd[0], "", &sb, AT_EMPTY_PATH) == 0,
851             FMT_ERR("fstatat pipe"));
852         ATF_REQUIRE_ERRNO(EFAULT, fstatat(fd[0], NULL, &sb,
853             AT_EMPTY_PATH) == -1);
854         CHECKED_CLOSE(fd[0]);
855         CHECKED_CLOSE(fd[1]);
856 }
857
858 /* Verify that we can send an O_PATH descriptor over a unix socket. */
859 ATF_TC_WITHOUT_HEAD(path_rights);
860 ATF_TC_BODY(path_rights, tc)
861 {
862         char path[PATH_MAX];
863         struct cmsghdr *cmsg;
864         struct msghdr msg;
865         struct iovec iov;
866         int flags, pathfd, pathfd_copy, sd[2];
867         char c;
868
869         ATF_REQUIRE_MSG(socketpair(PF_LOCAL, SOCK_STREAM, 0, sd) == 0,
870             FMT_ERR("socketpair"));
871
872         mktfile(path, "path_rights.XXXXXX");
873
874         pathfd = open(path, O_PATH);
875         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
876
877         /* Package up the O_PATH and send it over the socket pair. */
878         cmsg = malloc(CMSG_SPACE(sizeof(pathfd)));
879         ATF_REQUIRE_MSG(cmsg != NULL, FMT_ERR("malloc"));
880
881         cmsg->cmsg_len = CMSG_LEN(sizeof(pathfd));
882         cmsg->cmsg_level = SOL_SOCKET;
883         cmsg->cmsg_type = SCM_RIGHTS;
884         *(int *)(void *)CMSG_DATA(cmsg) = pathfd;
885
886         c = 0;
887         iov.iov_base = &c;
888         iov.iov_len = 1;
889
890         memset(&msg, 0, sizeof(msg));
891         msg.msg_iov = &iov;
892         msg.msg_iovlen = 1;
893         msg.msg_control = cmsg;
894         msg.msg_controllen = CMSG_SPACE(sizeof(pathfd));
895
896         ATF_REQUIRE_MSG(sendmsg(sd[0], &msg, 0) == sizeof(c),
897             FMT_ERR("sendmsg"));
898
899         /* Grab the pathfd copy from the other end of the pair. */
900         memset(&msg, 0, sizeof(msg));
901         msg.msg_iov = &iov;
902         msg.msg_iovlen = 1;
903         msg.msg_control = cmsg;
904         msg.msg_controllen = CMSG_SPACE(sizeof(pathfd));
905
906         ATF_REQUIRE_MSG(recvmsg(sd[1], &msg, 0) == 1,
907             FMT_ERR("recvmsg"));
908         pathfd_copy = *(int *)(void *)CMSG_DATA(cmsg);
909         ATF_REQUIRE_MSG(pathfd_copy != pathfd,
910             "pathfd and pathfd_copy are equal");
911
912         /* Verify that the copy has O_PATH properties. */
913         flags = fcntl(pathfd_copy, F_GETFL);
914         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
915         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH is not set");
916         ATF_REQUIRE_ERRNO(EBADF,
917             read(pathfd_copy, &c, 1) == -1);
918         ATF_REQUIRE_ERRNO(EBADF,
919             write(pathfd_copy, &c, 1) == -1);
920
921         CHECKED_CLOSE(pathfd);
922         CHECKED_CLOSE(pathfd_copy);
923         CHECKED_CLOSE(sd[0]);
924         CHECKED_CLOSE(sd[1]);
925 }
926
927 /* Verify that a local socket can be opened with O_PATH. */
928 ATF_TC_WITHOUT_HEAD(path_unix);
929 ATF_TC_BODY(path_unix, tc)
930 {
931         char buf[BUFSIZ], path[PATH_MAX];
932         struct kevent ev;
933         struct sockaddr_un sun;
934         struct stat sb;
935         int kq, pathfd, sd;
936
937         snprintf(path, sizeof(path), "path_unix.XXXXXX");
938         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
939
940         sd = socket(PF_LOCAL, SOCK_STREAM, 0);
941         ATF_REQUIRE_MSG(sd >= 0, FMT_ERR("socket"));
942
943         memset(&sun, 0, sizeof(sun));
944         sun.sun_family = PF_LOCAL;
945         (void)strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
946         ATF_REQUIRE_MSG(bind(sd, (struct sockaddr *)&sun, SUN_LEN(&sun)) == 0,
947             FMT_ERR("bind"));
948
949         pathfd = open(path, O_PATH);
950         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
951
952         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
953             FMT_ERR("fstatat"));
954         ATF_REQUIRE_MSG(sb.st_mode & S_IFSOCK, "socket mode %#x", sb.st_mode);
955         ATF_REQUIRE_MSG(sb.st_ino != 0, "socket has inode number 0");
956
957         memset(buf, 0, sizeof(buf));
958         ATF_REQUIRE_ERRNO(EBADF, write(pathfd, buf, sizeof(buf)));
959         ATF_REQUIRE_ERRNO(EBADF, read(pathfd, buf, sizeof(buf)));
960
961         /* kevent() is disallowed with sockets. */
962         kq = kqueue();
963         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
964         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
965         ATF_REQUIRE_ERRNO(EBADF, kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
966
967         /* Should not be able to open a socket without O_PATH. */
968         ATF_REQUIRE_ERRNO(EOPNOTSUPP, openat(pathfd, "", O_EMPTY_PATH) == -1);
969
970         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
971             FMT_ERR("funlinkat"));
972
973         CHECKED_CLOSE(sd);
974         CHECKED_CLOSE(pathfd);
975 }
976
977 /*
978  * Check that we can perform operations using an O_PATH fd for an unlinked file.
979  */
980 ATF_TC_WITHOUT_HEAD(path_unlinked);
981 ATF_TC_BODY(path_unlinked, tc)
982 {
983         char path[PATH_MAX];
984         struct stat sb;
985         int pathfd;
986
987         mktfile(path, "path_rights.XXXXXX");
988
989         pathfd = open(path, O_PATH);
990         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
991
992         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
993             FMT_ERR("fstatat"));
994         ATF_REQUIRE(sb.st_nlink == 1);
995         ATF_REQUIRE_MSG(fstat(pathfd, &sb) == 0, FMT_ERR("fstat"));
996         ATF_REQUIRE(sb.st_nlink == 1);
997
998         ATF_REQUIRE_MSG(unlink(path) == 0, FMT_ERR("unlink"));
999
1000         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
1001             FMT_ERR("fstatat"));
1002         ATF_REQUIRE(sb.st_nlink == 0);
1003         ATF_REQUIRE_MSG(fstat(pathfd, &sb) == 0, FMT_ERR("fstat"));
1004         ATF_REQUIRE(sb.st_nlink == 0);
1005
1006         CHECKED_CLOSE(pathfd);
1007 }
1008
1009 ATF_TP_ADD_TCS(tp)
1010 {
1011         ATF_TP_ADD_TC(tp, path_access);
1012         ATF_TP_ADD_TC(tp, path_aio);
1013         ATF_TP_ADD_TC(tp, path_capsicum);
1014         ATF_TP_ADD_TC(tp, path_capsicum_empty);
1015         ATF_TP_ADD_TC(tp, path_coredump);
1016         ATF_TP_ADD_TC(tp, path_directory);
1017         ATF_TP_ADD_TC(tp, path_directory_not_root);
1018         ATF_TP_ADD_TC(tp, path_empty);
1019         ATF_TP_ADD_TC(tp, path_empty_not_root);
1020         ATF_TP_ADD_TC(tp, path_empty_root);
1021         ATF_TP_ADD_TC(tp, path_event);
1022         ATF_TP_ADD_TC(tp, path_fcntl);
1023         ATF_TP_ADD_TC(tp, path_fexecve);
1024         ATF_TP_ADD_TC(tp, path_fifo);
1025         ATF_TP_ADD_TC(tp, path_funlinkat);
1026         ATF_TP_ADD_TC(tp, path_io);
1027         ATF_TP_ADD_TC(tp, path_ioctl);
1028         ATF_TP_ADD_TC(tp, path_lock);
1029         ATF_TP_ADD_TC(tp, path_pipe_fstatat);
1030         ATF_TP_ADD_TC(tp, path_rights);
1031         ATF_TP_ADD_TC(tp, path_unix);
1032         ATF_TP_ADD_TC(tp, path_unlinked);
1033
1034         return (atf_no_error());
1035 }