]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/file/path_test.c
sqlite3: Vendor import of sqlite3 3.39.3
[FreeBSD/FreeBSD.git] / tests / sys / file / path_test.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 /* Make sure that ptrace(PT_COREDUMP) cannot be used to write to a path fd. */
212 ATF_TC_WITHOUT_HEAD(path_coredump);
213 ATF_TC_BODY(path_coredump, tc)
214 {
215         char path[PATH_MAX];
216         struct ptrace_coredump pc;
217         int error, pathfd, status;
218         pid_t child;
219
220         mktdir(path, "path_coredump.XXXXXX");
221
222         child = fork();
223         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
224         if (child == 0) {
225                 while (true)
226                         (void)sleep(1);
227         }
228
229         pathfd = open(path, O_PATH);
230         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
231
232         error = ptrace(PT_ATTACH, child, 0, 0);
233         ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
234         error = waitpid(child, &status, 0);
235         ATF_REQUIRE_MSG(error != -1, FMT_ERR("waitpid"));
236         ATF_REQUIRE_MSG(WIFSTOPPED(status), "unexpected status %d", status);
237
238         pc.pc_fd = pathfd;
239         pc.pc_flags = 0;
240         pc.pc_limit = 0;
241         error = ptrace(PT_COREDUMP, child, (void *)&pc, sizeof(pc));
242         ATF_REQUIRE_ERRNO(EBADF, error == -1);
243
244         error = ptrace(PT_DETACH, child, 0, 0);
245         ATF_REQUIRE_MSG(error == 0, FMT_ERR("ptrace"));
246
247         ATF_REQUIRE_MSG(kill(child, SIGKILL) == 0, FMT_ERR("kill"));
248
249         CHECKED_CLOSE(pathfd);
250 }
251
252 /* Verify operations on directory path descriptors. */
253 ATF_TC_WITHOUT_HEAD(path_directory);
254 ATF_TC_BODY(path_directory, tc)
255 {
256         struct dirent de;
257         struct stat sb;
258         char path[PATH_MAX];
259         int fd, pathfd;
260
261         mktdir(path, "path_directory.XXXXXX");
262
263         pathfd = open(path, O_PATH | O_DIRECTORY);
264         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
265
266         /* Should not be possible to list directory entries. */
267         ATF_REQUIRE_ERRNO(EBADF,
268             getdirentries(pathfd, (char *)&de, sizeof(de), NULL) == -1);
269
270         /* It should be possible to create files under pathfd. */
271         fd = openat(pathfd, "test", O_RDWR | O_CREAT, 0600);
272         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
273         ATF_REQUIRE_MSG(fstatat(pathfd, "test", &sb, 0) == 0,
274             FMT_ERR("fstatat"));
275         CHECKED_CLOSE(fd);
276
277         /* ... but doing so requires write access. */
278         if (geteuid() != 0) {
279                 ATF_REQUIRE_ERRNO(EBADF, fchmod(pathfd, 0500) == -1);
280                 ATF_REQUIRE_MSG(chmod(path, 0500) == 0, FMT_ERR("chmod"));
281                 ATF_REQUIRE_ERRNO(EACCES,
282                     openat(pathfd, "test2", O_RDWR | O_CREAT, 0600) < 0);
283         }
284
285         /* fchdir(2) is permitted. */
286         ATF_REQUIRE_MSG(fchdir(pathfd) == 0, FMT_ERR("fchdir"));
287
288         CHECKED_CLOSE(pathfd);
289 }
290
291 /* Verify access permission checking for a directory path fd. */
292 ATF_TC_WITH_CLEANUP(path_directory_not_root);
293 ATF_TC_HEAD(path_directory_not_root, tc)
294 {
295         atf_tc_set_md_var(tc, "require.user", "unprivileged");
296 }
297 ATF_TC_BODY(path_directory_not_root, tc)
298 {
299         char path[PATH_MAX];
300         int pathfd;
301
302         mktdir(path, "path_directory.XXXXXX");
303
304         pathfd = open(path, O_PATH | O_DIRECTORY);
305         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
306
307         ATF_REQUIRE_ERRNO(EBADF, fchmod(pathfd, 0500) == -1);
308         ATF_REQUIRE_MSG(chmod(path, 0500) == 0, FMT_ERR("chmod"));
309         ATF_REQUIRE_ERRNO(EACCES,
310             openat(pathfd, "test2", O_RDWR | O_CREAT, 0600) < 0);
311
312         CHECKED_CLOSE(pathfd);
313 }
314 ATF_TC_CLEANUP(path_directory_not_root, tc)
315 {
316 }
317
318 /* Validate system calls that handle AT_EMPTY_PATH. */
319 ATF_TC_WITHOUT_HEAD(path_empty);
320 ATF_TC_BODY(path_empty, tc)
321 {
322         char path[PATH_MAX];
323         struct timespec ts[2];
324         struct stat sb;
325         int pathfd;
326
327         mktfile(path, "path_empty.XXXXXX");
328
329         pathfd = open(path, O_PATH);
330         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
331
332         /* Various *at operations should work on path fds. */
333         ATF_REQUIRE_MSG(faccessat(pathfd, "", F_OK, AT_EMPTY_PATH) == 0,
334             FMT_ERR("faccessat"));
335         ATF_REQUIRE_MSG(chflagsat(pathfd, "", UF_NODUMP, AT_EMPTY_PATH) == 0,
336             FMT_ERR("chflagsat"));
337         ATF_REQUIRE_MSG(fchmodat(pathfd, "", 0600, AT_EMPTY_PATH) == 0,
338             FMT_ERR("fchmodat"));
339         ATF_REQUIRE_MSG(fchownat(pathfd, "", getuid(), getgid(),
340             AT_EMPTY_PATH) == 0, FMT_ERR("fchownat"));
341         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
342             FMT_ERR("fstatat"));
343         ATF_REQUIRE_MSG(sb.st_size == BUFSIZ,
344             "unexpected size %ju", (uintmax_t)sb.st_size);
345         memset(ts, 0, sizeof(ts));
346         ATF_REQUIRE_MSG(utimensat(pathfd, "", ts, AT_EMPTY_PATH) == 0,
347             FMT_ERR("utimensat"));
348
349         CHECKED_CLOSE(pathfd);
350 }
351
352 /* Verify that various operations on a path fd have access checks. */
353 ATF_TC_WITH_CLEANUP(path_empty_not_root);
354 ATF_TC_HEAD(path_empty_not_root, tc)
355 {
356         atf_tc_set_md_var(tc, "require.user", "unprivileged");
357 }
358 ATF_TC_BODY(path_empty_not_root, tc)
359 {
360         int pathfd;
361
362         pathfd = open("/dev/null", O_PATH);
363         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
364
365         ATF_REQUIRE_ERRNO(EPERM,
366             chflagsat(pathfd, "", UF_NODUMP, AT_EMPTY_PATH) == -1);
367         ATF_REQUIRE_ERRNO(EPERM,
368             fchownat(pathfd, "", getuid(), getgid(), AT_EMPTY_PATH) == -1);
369         ATF_REQUIRE_ERRNO(EPERM,
370             fchmodat(pathfd, "", 0600, AT_EMPTY_PATH) == -1);
371         ATF_REQUIRE_ERRNO(EPERM,
372             linkat(pathfd, "", AT_FDCWD, "test", AT_EMPTY_PATH) == -1);
373
374         CHECKED_CLOSE(pathfd);
375 }
376 ATF_TC_CLEANUP(path_empty_not_root, tc)
377 {
378 }
379
380 /* Test linkat(2) with AT_EMPTY_PATH, which requires privileges. */
381 ATF_TC_WITH_CLEANUP(path_empty_root);
382 ATF_TC_HEAD(path_empty_root, tc)
383 {
384         atf_tc_set_md_var(tc, "require.user", "root");
385 }
386 ATF_TC_BODY(path_empty_root, tc)
387 {
388         char path[PATH_MAX];
389         struct stat sb, sb2;
390         int pathfd;
391
392         mktfile(path, "path_empty_root.XXXXXX");
393
394         pathfd = open(path, O_PATH);
395         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
396         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
397             FMT_ERR("fstatat"));
398
399         ATF_REQUIRE_MSG(linkat(pathfd, "", AT_FDCWD, "test", AT_EMPTY_PATH) ==
400             0, FMT_ERR("linkat"));
401         ATF_REQUIRE_MSG(fstatat(AT_FDCWD, "test", &sb2, 0) == 0,
402             FMT_ERR("fstatat"));
403         ATF_REQUIRE_MSG(sb.st_dev == sb2.st_dev, "st_dev mismatch");
404         ATF_REQUIRE_MSG(sb.st_ino == sb2.st_ino, "st_ino mismatch");
405
406         CHECKED_CLOSE(pathfd);
407
408 }
409 ATF_TC_CLEANUP(path_empty_root, tc)
410 {
411 }
412
413 /* poll(2) never returns an event for path fds, but kevent(2) does. */
414 ATF_TC_WITHOUT_HEAD(path_event);
415 ATF_TC_BODY(path_event, tc)
416 {
417         char buf[BUFSIZ], path[PATH_MAX];
418         struct kevent ev;
419         struct pollfd pollfd;
420         int kq, pathfd;
421
422         mktfile(path, "path_event.XXXXXX");
423
424         pathfd = open(path, O_PATH);
425         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
426
427         /* poll(2) should return POLLNVAL. */
428         pollfd.fd = pathfd;
429         pollfd.events = POLLIN;
430         pollfd.revents = 0;
431         ATF_REQUIRE_MSG(poll(&pollfd, 1, 0) == 1, FMT_ERR("poll"));
432         ATF_REQUIRE_MSG(pollfd.revents == POLLNVAL, "unexpected revents %x",
433             pollfd.revents);
434         pollfd.events = POLLOUT;
435         pollfd.revents = 0;
436         ATF_REQUIRE_MSG(poll(&pollfd, 1, 0) == 1, FMT_ERR("poll"));
437         ATF_REQUIRE_MSG(pollfd.revents == POLLNVAL, "unexpected revents %x",
438             pollfd.revents);
439
440         /* Try to get a EVFILT_READ event through a path fd. */
441         kq = kqueue();
442         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
443         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
444         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
445             FMT_ERR("kevent"));
446         ATF_REQUIRE_MSG(kevent(kq, NULL, 0, &ev, 1, NULL) == 1,
447             FMT_ERR("kevent"));
448         ATF_REQUIRE_MSG((ev.flags & EV_ERROR) == 0, "EV_ERROR is set");
449         ATF_REQUIRE_MSG(ev.data == sizeof(buf),
450             "data is %jd", (intmax_t)ev.data);
451         EV_SET(&ev, pathfd, EVFILT_READ, EV_DELETE, 0, 0, 0);
452         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
453             FMT_ERR("kevent"));
454
455         /* Try to get a EVFILT_VNODE/NOTE_DELETE event through a path fd. */
456         EV_SET(&ev, pathfd, EVFILT_VNODE, EV_ADD | EV_ENABLE, NOTE_DELETE, 0,
457             0);
458         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
459             FMT_ERR("kevent"));
460         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
461             FMT_ERR("funlinkat"));
462         ATF_REQUIRE_MSG(kevent(kq, NULL, 0, &ev, 1, NULL) == 1,
463             FMT_ERR("kevent"));
464         ATF_REQUIRE_MSG(ev.fflags == NOTE_DELETE,
465             "unexpected fflags %#x", ev.fflags);
466         EV_SET(&ev, pathfd, EVFILT_VNODE, EV_DELETE, 0, 0, 0);
467         ATF_REQUIRE_MSG(kevent(kq, &ev, 1, NULL, 0, NULL) == 0,
468             FMT_ERR("kevent"));
469
470         CHECKED_CLOSE(kq);
471         CHECKED_CLOSE(pathfd);
472 }
473
474 /* Check various fcntl(2) operations on a path desriptor. */
475 ATF_TC_WITHOUT_HEAD(path_fcntl);
476 ATF_TC_BODY(path_fcntl, tc)
477 {
478         char path[PATH_MAX];
479         int flags, pathfd, pathfd2;
480
481         mktfile(path, "path_fcntl.XXXXXX");
482
483         pathfd = open(path, O_PATH);
484         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
485
486         /* O_PATH should appear in the fd flags. */
487         flags = fcntl(pathfd, F_GETFL);
488         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
489         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
490
491         ATF_REQUIRE_ERRNO(EBADF,
492             fcntl(pathfd, F_SETFL, flags & ~O_PATH));
493         ATF_REQUIRE_ERRNO(EBADF,
494             fcntl(pathfd, F_SETFL, flags | O_APPEND));
495
496         /* A dup'ed O_PATH fd had better have O_PATH set too. */
497         pathfd2 = fcntl(pathfd, F_DUPFD, 0);
498         ATF_REQUIRE_MSG(pathfd2 >= 0, FMT_ERR("fcntl"));
499         flags = fcntl(pathfd2, F_GETFL);
500         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
501         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
502         CHECKED_CLOSE(pathfd2);
503
504         /* Double check with dup(2). */
505         pathfd2 = dup(pathfd);
506         ATF_REQUIRE_MSG(pathfd2 >= 0, FMT_ERR("dup"));
507         flags = fcntl(pathfd2, F_GETFL);
508         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
509         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH not set");
510         CHECKED_CLOSE(pathfd2);
511
512         /* It should be possible to set O_CLOEXEC. */
513         ATF_REQUIRE_MSG(fcntl(pathfd, F_SETFD, FD_CLOEXEC) == 0,
514             FMT_ERR("fcntl"));
515         ATF_REQUIRE_MSG(fcntl(pathfd, F_GETFD) == FD_CLOEXEC,
516             FMT_ERR("fcntl"));
517
518         CHECKED_CLOSE(pathfd);
519 }
520
521 /* Verify that we can execute a file opened with O_PATH. */
522 ATF_TC_WITHOUT_HEAD(path_fexecve);
523 ATF_TC_BODY(path_fexecve, tc)
524 {
525         char path[PATH_MAX];
526         pid_t child;
527         int fd, pathfd;
528
529         child = fork();
530         ATF_REQUIRE_MSG(child != -1, FMT_ERR("fork"));
531         if (child == 0) {
532                 pathfd = open("/usr/bin/true", O_PATH | O_EXEC);
533                 if (pathfd < 0)
534                         _exit(1);
535                 fexecve(pathfd,
536                     (char * const[]){__DECONST(char *, "/usr/bin/true"), NULL},
537                     NULL);
538                 _exit(2);
539         }
540         waitchild(child, 0);
541
542         /*
543          * Also verify that access permissions are checked when opening with
544          * O_PATH.
545          */
546         snprintf(path, sizeof(path), "path_fexecve.XXXXXX");
547         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
548
549         fd = open(path, O_CREAT | O_RDONLY, 0600);
550         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("open"));
551
552         pathfd = open(path, O_PATH | O_EXEC);
553         ATF_REQUIRE_ERRNO(EACCES, pathfd < 0);
554 }
555
556 /* Make sure that O_PATH restrictions apply to named pipes as well. */
557 ATF_TC_WITHOUT_HEAD(path_fifo);
558 ATF_TC_BODY(path_fifo, tc)
559 {
560         char path[PATH_MAX], buf[BUFSIZ];
561         struct kevent ev;
562         int kq, pathfd;
563
564         snprintf(path, sizeof(path), "path_fifo.XXXXXX");
565         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
566
567         ATF_REQUIRE_MSG(mkfifo(path, 0666) == 0, FMT_ERR("mkfifo"));
568
569         pathfd = open(path, O_PATH);
570         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
571         memset(buf, 0, sizeof(buf));
572         ATF_REQUIRE_ERRNO(EBADF, write(pathfd, buf, sizeof(buf)));
573         ATF_REQUIRE_ERRNO(EBADF, read(pathfd, buf, sizeof(buf)));
574
575         kq = kqueue();
576         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
577         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
578         ATF_REQUIRE_ERRNO(EBADF, kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
579
580         CHECKED_CLOSE(pathfd);
581 }
582
583 /* Files may be unlinked using a path fd. */
584 ATF_TC_WITHOUT_HEAD(path_funlinkat);
585 ATF_TC_BODY(path_funlinkat, tc)
586 {
587         char path[PATH_MAX];
588         struct stat sb;
589         int pathfd;
590
591         mktfile(path, "path_rights.XXXXXX");
592
593         pathfd = open(path, O_PATH);
594         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
595
596         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
597             FMT_ERR("funlinkat"));
598         ATF_REQUIRE_ERRNO(ENOENT, stat(path, &sb) == -1);
599
600         CHECKED_CLOSE(pathfd);
601 }
602
603 /* Verify that various I/O operations fail on an O_PATH descriptor. */
604 ATF_TC_WITHOUT_HEAD(path_io);
605 ATF_TC_BODY(path_io, tc)
606 {
607         char path[PATH_MAX], path2[PATH_MAX];
608         char buf[BUFSIZ];
609         struct iovec iov;
610         size_t page_size;
611         int error, fd, pathfd, sd[2];
612
613         /* It shouldn't be possible to create new files with O_PATH. */
614         snprintf(path, sizeof(path), "path_io.XXXXXX");
615         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
616         ATF_REQUIRE_ERRNO(ENOENT, open(path, O_PATH | O_CREAT, 0600) < 0);
617
618         /* Create a non-empty file for use in the rest of the tests. */
619         mktfile(path, "path_io.XXXXXX");
620
621         pathfd = open(path, O_PATH);
622         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
623
624         /* Make sure that basic I/O operations aren't possible. */
625         iov.iov_base = path;
626         iov.iov_len = strlen(path);
627         ATF_REQUIRE_ERRNO(EBADF,
628             write(pathfd, iov.iov_base, iov.iov_len) == -1);
629         ATF_REQUIRE_ERRNO(EBADF,
630             pwrite(pathfd, iov.iov_base, iov.iov_len, 0) == -1);
631         ATF_REQUIRE_ERRNO(EBADF,
632             writev(pathfd, &iov, 1) == -1);
633         ATF_REQUIRE_ERRNO(EBADF,
634             pwritev(pathfd, &iov, 1, 0) == -1);
635         ATF_REQUIRE_ERRNO(EBADF,
636             read(pathfd, path, 1) == -1);
637         ATF_REQUIRE_ERRNO(EBADF,
638             pread(pathfd, path, 1, 0) == -1);
639         ATF_REQUIRE_ERRNO(EBADF,
640             readv(pathfd, &iov, 1) == -1);
641         ATF_REQUIRE_ERRNO(EBADF,
642             preadv(pathfd, &iov, 1, 0) == -1);
643
644         /* copy_file_range() should not be permitted. */
645         mktfile(path2, "path_io.XXXXXX");
646         fd = open(path2, O_RDWR);
647         ATF_REQUIRE_ERRNO(EBADF,
648             copy_file_range(fd, NULL, pathfd, NULL, sizeof(buf), 0) == -1);
649         ATF_REQUIRE_ERRNO(EBADF,
650             copy_file_range(pathfd, NULL, fd, NULL, sizeof(buf), 0) == -1);
651         CHECKED_CLOSE(fd);
652
653         /* sendfile() should not be permitted. */
654         ATF_REQUIRE_MSG(socketpair(PF_LOCAL, SOCK_STREAM, 0, sd) == 0,
655             FMT_ERR("socketpair"));
656         ATF_REQUIRE_ERRNO(EBADF,
657             sendfile(pathfd, sd[0], 0, 0, NULL, NULL, 0));
658         CHECKED_CLOSE(sd[0]);
659         CHECKED_CLOSE(sd[1]);
660
661         /* No seeking. */
662         ATF_REQUIRE_ERRNO(ESPIPE,
663             lseek(pathfd, 0, SEEK_SET) == -1);
664
665         /* No operations on the file extent. */
666         ATF_REQUIRE_ERRNO(EINVAL,
667             ftruncate(pathfd, 0) == -1);
668         error = posix_fallocate(pathfd, 0, sizeof(buf) * 2);
669         ATF_REQUIRE_MSG(error == ESPIPE, "posix_fallocate() returned %d", error);
670         error = posix_fadvise(pathfd, 0, sizeof(buf), POSIX_FADV_NORMAL);
671         ATF_REQUIRE_MSG(error == ESPIPE, "posix_fadvise() returned %d", error);
672
673         /* mmap() is not allowed. */
674         page_size = getpagesize();
675         ATF_REQUIRE_ERRNO(ENODEV,
676             mmap(NULL, page_size, PROT_READ, MAP_SHARED, pathfd, 0) ==
677             MAP_FAILED);
678         ATF_REQUIRE_ERRNO(ENODEV,
679             mmap(NULL, page_size, PROT_NONE, MAP_SHARED, pathfd, 0) ==
680             MAP_FAILED);
681         ATF_REQUIRE_ERRNO(ENODEV,
682             mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, pathfd, 0) ==
683             MAP_FAILED);
684
685         /* No fsync() or fdatasync(). */
686         ATF_REQUIRE_ERRNO(EBADF, fsync(pathfd) == -1);
687         ATF_REQUIRE_ERRNO(EBADF, fdatasync(pathfd) == -1);
688
689         CHECKED_CLOSE(pathfd);
690 }
691
692 /* ioctl(2) is not permitted on path fds. */
693 ATF_TC_WITHOUT_HEAD(path_ioctl);
694 ATF_TC_BODY(path_ioctl, tc)
695 {
696         char path[PATH_MAX];
697         struct mem_extract me;
698         int pathfd, val;
699
700         mktfile(path, "path_ioctl.XXXXXX");
701
702         /* Standard file descriptor ioctls should fail. */
703         pathfd = open(path, O_PATH);
704         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
705
706         val = 0;
707         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONBIO, &val) == -1);
708         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONREAD, &val) == -1);
709         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONWRITE, &val) == -1);
710         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, FIONSPACE, &val) == -1);
711
712         CHECKED_CLOSE(pathfd);
713
714         /* Device ioctls should fail. */
715         pathfd = open("/dev/mem", O_PATH);
716         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
717
718         me.me_vaddr = (uintptr_t)&me;
719         ATF_REQUIRE_ERRNO(EBADF, ioctl(pathfd, MEM_EXTRACT_PADDR, &me) == -1);
720
721         CHECKED_CLOSE(pathfd);
722 }
723
724 ATF_TC_WITHOUT_HEAD(path_lock);
725 ATF_TC_BODY(path_lock, tc)
726 {
727         char buf[BUFSIZ], path[PATH_MAX];
728         struct flock flk;
729         int fd, pathfd;
730
731         snprintf(path, sizeof(path), "path_rights.XXXXXX");
732         fd = mkostemp(path, O_SHLOCK);
733         ATF_REQUIRE_MSG(fd >= 0, FMT_ERR("mkostemp"));
734         memset(buf, 0, sizeof(buf));
735         ATF_REQUIRE_MSG(write(fd, buf, sizeof(buf)) == sizeof(buf),
736             FMT_ERR("write()"));
737
738         /* Verify that O_EXLOCK is ignored when combined with O_PATH. */
739         pathfd = open(path, O_PATH | O_EXLOCK);
740         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
741
742         CHECKED_CLOSE(fd);
743
744         /* flock(2) is prohibited. */
745         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_SH) == -1);
746         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_EX) == -1);
747         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_SH | LOCK_NB) == -1);
748         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_EX | LOCK_NB) == -1);
749         ATF_REQUIRE_ERRNO(EOPNOTSUPP, flock(pathfd, LOCK_UN) == -1);
750
751         /* fcntl(2) file locks are prohibited. */
752         memset(&flk, 0, sizeof(flk));
753         flk.l_whence = SEEK_CUR;
754         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_GETLK, &flk) == -1);
755         flk.l_type = F_RDLCK;
756         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLK, &flk) == -1);
757         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLKW, &flk) == -1);
758         flk.l_type = F_WRLCK;
759         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLK, &flk) == -1);
760         ATF_REQUIRE_ERRNO(EBADF, fcntl(pathfd, F_SETLKW, &flk) == -1);
761
762         CHECKED_CLOSE(pathfd);
763 }
764
765 /*
766  * Verify fstatat(AT_EMPTY_PATH) on non-regular dirfd.
767  * Verify that fstatat(AT_EMPTY_PATH) on NULL path returns EFAULT.
768  */
769 ATF_TC_WITHOUT_HEAD(path_pipe_fstatat);
770 ATF_TC_BODY(path_pipe_fstatat, tc)
771 {
772         struct stat sb;
773         int fd[2];
774
775         ATF_REQUIRE_MSG(pipe(fd) == 0, FMT_ERR("pipe"));
776         ATF_REQUIRE_MSG(fstatat(fd[0], "", &sb, AT_EMPTY_PATH) == 0,
777             FMT_ERR("fstatat pipe"));
778         ATF_REQUIRE_ERRNO(EFAULT, fstatat(fd[0], NULL, &sb,
779             AT_EMPTY_PATH) == -1);
780         CHECKED_CLOSE(fd[0]);
781         CHECKED_CLOSE(fd[1]);
782 }
783
784 /* Verify that we can send an O_PATH descriptor over a unix socket. */
785 ATF_TC_WITHOUT_HEAD(path_rights);
786 ATF_TC_BODY(path_rights, tc)
787 {
788         char path[PATH_MAX];
789         struct cmsghdr *cmsg;
790         struct msghdr msg;
791         struct iovec iov;
792         int flags, pathfd, pathfd_copy, sd[2];
793         char c;
794
795         ATF_REQUIRE_MSG(socketpair(PF_LOCAL, SOCK_STREAM, 0, sd) == 0,
796             FMT_ERR("socketpair"));
797
798         mktfile(path, "path_rights.XXXXXX");
799
800         pathfd = open(path, O_PATH);
801         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
802
803         /* Package up the O_PATH and send it over the socket pair. */
804         cmsg = malloc(CMSG_SPACE(sizeof(pathfd)));
805         ATF_REQUIRE_MSG(cmsg != NULL, FMT_ERR("malloc"));
806
807         cmsg->cmsg_len = CMSG_LEN(sizeof(pathfd));
808         cmsg->cmsg_level = SOL_SOCKET;
809         cmsg->cmsg_type = SCM_RIGHTS;
810         *(int *)(void *)CMSG_DATA(cmsg) = pathfd;
811
812         c = 0;
813         iov.iov_base = &c;
814         iov.iov_len = 1;
815
816         memset(&msg, 0, sizeof(msg));
817         msg.msg_iov = &iov;
818         msg.msg_iovlen = 1;
819         msg.msg_control = cmsg;
820         msg.msg_controllen = CMSG_SPACE(sizeof(pathfd));
821
822         ATF_REQUIRE_MSG(sendmsg(sd[0], &msg, 0) == sizeof(c),
823             FMT_ERR("sendmsg"));
824
825         /* Grab the pathfd copy from the other end of the pair. */
826         memset(&msg, 0, sizeof(msg));
827         msg.msg_iov = &iov;
828         msg.msg_iovlen = 1;
829         msg.msg_control = cmsg;
830         msg.msg_controllen = CMSG_SPACE(sizeof(pathfd));
831
832         ATF_REQUIRE_MSG(recvmsg(sd[1], &msg, 0) == 1,
833             FMT_ERR("recvmsg"));
834         pathfd_copy = *(int *)(void *)CMSG_DATA(cmsg);
835         ATF_REQUIRE_MSG(pathfd_copy != pathfd,
836             "pathfd and pathfd_copy are equal");
837
838         /* Verify that the copy has O_PATH properties. */
839         flags = fcntl(pathfd_copy, F_GETFL);
840         ATF_REQUIRE_MSG(flags != -1, FMT_ERR("fcntl"));
841         ATF_REQUIRE_MSG((flags & O_PATH) != 0, "O_PATH is not set");
842         ATF_REQUIRE_ERRNO(EBADF,
843             read(pathfd_copy, &c, 1) == -1);
844         ATF_REQUIRE_ERRNO(EBADF,
845             write(pathfd_copy, &c, 1) == -1);
846
847         CHECKED_CLOSE(pathfd);
848         CHECKED_CLOSE(pathfd_copy);
849         CHECKED_CLOSE(sd[0]);
850         CHECKED_CLOSE(sd[1]);
851 }
852
853 /* Verify that a local socket can be opened with O_PATH. */
854 ATF_TC_WITHOUT_HEAD(path_unix);
855 ATF_TC_BODY(path_unix, tc)
856 {
857         char buf[BUFSIZ], path[PATH_MAX];
858         struct kevent ev;
859         struct sockaddr_un sun;
860         struct stat sb;
861         int kq, pathfd, sd;
862
863         snprintf(path, sizeof(path), "path_unix.XXXXXX");
864         ATF_REQUIRE_MSG(mktemp(path) == path, FMT_ERR("mktemp"));
865
866         sd = socket(PF_LOCAL, SOCK_STREAM, 0);
867         ATF_REQUIRE_MSG(sd >= 0, FMT_ERR("socket"));
868
869         memset(&sun, 0, sizeof(sun));
870         sun.sun_family = PF_LOCAL;
871         (void)strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
872         ATF_REQUIRE_MSG(bind(sd, (struct sockaddr *)&sun, SUN_LEN(&sun)) == 0,
873             FMT_ERR("bind"));
874
875         pathfd = open(path, O_PATH);
876         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
877
878         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
879             FMT_ERR("fstatat"));
880         ATF_REQUIRE_MSG(sb.st_mode & S_IFSOCK, "socket mode %#x", sb.st_mode);
881         ATF_REQUIRE_MSG(sb.st_ino != 0, "socket has inode number 0");
882
883         memset(buf, 0, sizeof(buf));
884         ATF_REQUIRE_ERRNO(EBADF, write(pathfd, buf, sizeof(buf)));
885         ATF_REQUIRE_ERRNO(EBADF, read(pathfd, buf, sizeof(buf)));
886
887         /* kevent() is disallowed with sockets. */
888         kq = kqueue();
889         ATF_REQUIRE_MSG(kq >= 0, FMT_ERR("kqueue"));
890         EV_SET(&ev, pathfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
891         ATF_REQUIRE_ERRNO(EBADF, kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
892
893         /* Should not be able to open a socket without O_PATH. */
894         ATF_REQUIRE_ERRNO(EOPNOTSUPP, openat(pathfd, "", O_EMPTY_PATH) == -1);
895
896         ATF_REQUIRE_MSG(funlinkat(AT_FDCWD, path, pathfd, 0) == 0,
897             FMT_ERR("funlinkat"));
898
899         CHECKED_CLOSE(sd);
900         CHECKED_CLOSE(pathfd);
901 }
902
903 /*
904  * Check that we can perform operations using an O_PATH fd for an unlinked file.
905  */
906 ATF_TC_WITHOUT_HEAD(path_unlinked);
907 ATF_TC_BODY(path_unlinked, tc)
908 {
909         char path[PATH_MAX];
910         struct stat sb;
911         int pathfd;
912
913         mktfile(path, "path_rights.XXXXXX");
914
915         pathfd = open(path, O_PATH);
916         ATF_REQUIRE_MSG(pathfd >= 0, FMT_ERR("open"));
917
918         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
919             FMT_ERR("fstatat"));
920         ATF_REQUIRE(sb.st_nlink == 1);
921         ATF_REQUIRE_MSG(fstat(pathfd, &sb) == 0, FMT_ERR("fstat"));
922         ATF_REQUIRE(sb.st_nlink == 1);
923
924         ATF_REQUIRE_MSG(unlink(path) == 0, FMT_ERR("unlink"));
925
926         ATF_REQUIRE_MSG(fstatat(pathfd, "", &sb, AT_EMPTY_PATH) == 0,
927             FMT_ERR("fstatat"));
928         ATF_REQUIRE(sb.st_nlink == 0);
929         ATF_REQUIRE_MSG(fstat(pathfd, &sb) == 0, FMT_ERR("fstat"));
930         ATF_REQUIRE(sb.st_nlink == 0);
931
932         CHECKED_CLOSE(pathfd);
933 }
934
935 ATF_TP_ADD_TCS(tp)
936 {
937         ATF_TP_ADD_TC(tp, path_access);
938         ATF_TP_ADD_TC(tp, path_aio);
939         ATF_TP_ADD_TC(tp, path_capsicum);
940         ATF_TP_ADD_TC(tp, path_coredump);
941         ATF_TP_ADD_TC(tp, path_directory);
942         ATF_TP_ADD_TC(tp, path_directory_not_root);
943         ATF_TP_ADD_TC(tp, path_empty);
944         ATF_TP_ADD_TC(tp, path_empty_not_root);
945         ATF_TP_ADD_TC(tp, path_empty_root);
946         ATF_TP_ADD_TC(tp, path_event);
947         ATF_TP_ADD_TC(tp, path_fcntl);
948         ATF_TP_ADD_TC(tp, path_fexecve);
949         ATF_TP_ADD_TC(tp, path_fifo);
950         ATF_TP_ADD_TC(tp, path_funlinkat);
951         ATF_TP_ADD_TC(tp, path_io);
952         ATF_TP_ADD_TC(tp, path_ioctl);
953         ATF_TP_ADD_TC(tp, path_lock);
954         ATF_TP_ADD_TC(tp, path_pipe_fstatat);
955         ATF_TP_ADD_TC(tp, path_rights);
956         ATF_TP_ADD_TC(tp, path_unix);
957         ATF_TP_ADD_TC(tp, path_unlinked);
958
959         return (atf_no_error());
960 }