xref: /openbsd-src/regress/sys/kern/unveil/syscalls.c (revision 2c5685b9db4928888a1a2384f8eaf0070cec2f29)
1*2c5685b9Santon /*	$OpenBSD: syscalls.c,v 1.37 2024/09/03 04:59:03 anton Exp $	*/
20d000527Sbeck 
30d000527Sbeck /*
41939e486Sbeck  * Copyright (c) 2017-2019 Bob Beck <beck@openbsd.org>
50d000527Sbeck  *
60d000527Sbeck  * Permission to use, copy, modify, and distribute this software for any
70d000527Sbeck  * purpose with or without fee is hereby granted, provided that the above
80d000527Sbeck  * copyright notice and this permission notice appear in all copies.
90d000527Sbeck  *
100d000527Sbeck  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
110d000527Sbeck  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
120d000527Sbeck  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
130d000527Sbeck  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
140d000527Sbeck  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
150d000527Sbeck  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
160d000527Sbeck  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
170d000527Sbeck  */
180d000527Sbeck 
190d000527Sbeck #include <stdio.h>
200d000527Sbeck #include <unistd.h>
217676bde3Sbeck #include <dirent.h>
220d000527Sbeck #include <fcntl.h>
230d000527Sbeck #include <sys/mount.h>
240d000527Sbeck 
25b749d6b5Santon #include "unveil.h"
26d903b886Sclaudio 
270d000527Sbeck /* all the things unless we override */
2842b5d727Sbeck const char *uv_flags = "rwxc";
290d000527Sbeck 
300d000527Sbeck static void
310d000527Sbeck do_unveil(void)
320d000527Sbeck {
3342b5d727Sbeck 	if (unveil(uv_dir1, uv_flags) == -1)
340d000527Sbeck                 err(1, "%s:%d - unveil", __FILE__, __LINE__);
3542b5d727Sbeck 	if (unveil(uv_file1, uv_flags) == -1)
360d000527Sbeck                 err(1, "%s:%d - unveil", __FILE__, __LINE__);
370d000527Sbeck }
380d000527Sbeck 
39f195f92eSbeck static void
40f195f92eSbeck do_unveil2(void)
41f195f92eSbeck {
42f195f92eSbeck 	if (unveil(uv_dir1, uv_flags) == -1)
43f195f92eSbeck                 err(1, "%s:%d - unveil", __FILE__, __LINE__);
44f195f92eSbeck }
45f195f92eSbeck 
460d000527Sbeck static int
4768ea1b06Sbeck test_openat(int do_uv)
4868ea1b06Sbeck {
4968ea1b06Sbeck 	int slashbefore;
5068ea1b06Sbeck 	int dirfd1before;
5168ea1b06Sbeck 	int dirfd2before;
5268ea1b06Sbeck 	int dirfd1after;
5368ea1b06Sbeck 	int dirfd2after;
5468ea1b06Sbeck 	UV_SHOULD_SUCCEED(((slashbefore = open("/", O_RDONLY | O_DIRECTORY)) == -1), "open");
5568ea1b06Sbeck 	UV_SHOULD_SUCCEED(((dirfd1before = open(uv_dir1, O_RDONLY | O_DIRECTORY)) == -1), "open");
5668ea1b06Sbeck 	UV_SHOULD_SUCCEED(((dirfd2before = open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1), "open");
5768ea1b06Sbeck 	if (do_uv) {
5868ea1b06Sbeck 	  	printf("testing openat\n");
5968ea1b06Sbeck 		do_unveil();
6068ea1b06Sbeck 	}
6168ea1b06Sbeck 	UV_SHOULD_SUCCEED(((dirfd1after = open(uv_dir1, O_RDONLY | O_DIRECTORY)) == -1), "open");
6268ea1b06Sbeck 	UV_SHOULD_ENOENT(((dirfd2after = open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1), "open");
6368ea1b06Sbeck 
6468ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(slashbefore, "etc/hosts", O_RDONLY) == -1), "openat");
6568ea1b06Sbeck 	UV_SHOULD_SUCCEED((openat(slashbefore, uv_file1, O_RDWR) == -1), "openat");
6668ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(slashbefore, uv_file2, O_RDWR) == -1), "openat");
6768ea1b06Sbeck 
6868ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(dirfd1before, "/etc/hosts", O_RDONLY) == -1), "openat");
692a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd1before, "hooray", O_RDWR|O_CREAT, 0644) == -1), "openat");
702a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd1before, uv_file1, O_RDWR|O_CREAT, 0644) == -1), "openat");
712a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd1before, uv_file2, O_RDWR|O_CREAT, 0644) == -1), "openat");
7268ea1b06Sbeck 
7368ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(dirfd2before, "/etc/hosts", O_RDONLY) == -1), "openat");
742a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd2before, "hooray", O_RDWR|O_CREAT, 0644) == -1), "openat");
752a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd2before, uv_file1, O_RDWR|O_CREAT, 0644) == -1), "openat");
762a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd2before, uv_file2, O_RDWR|O_CREAT, 0644) == -1), "openat");
7768ea1b06Sbeck 
7868ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(dirfd1after, "/etc/hosts", O_RDONLY) == -1), "openat");
792a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd1after, "hooray", O_RDWR|O_CREAT, 0644) == -1), "openat");
802a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd1after, uv_file1, O_RDWR|O_CREAT, 0644) == -1), "openat");
812a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd1after, uv_file2, O_RDWR|O_CREAT, 0644) == -1), "openat");
8268ea1b06Sbeck 
8368ea1b06Sbeck 	UV_SHOULD_SUCCEED(((dirfd2after = openat(dirfd1after, "subdir",  O_RDONLY | O_DIRECTORY)) == -1), "openat");
842a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd2after, "../derp", O_RDWR|O_CREAT, 0644) == -1), "openat");
852a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd2after, "../../derpyluvs", O_RDWR|O_CREAT, 0644) == -1), "openat");
8668ea1b06Sbeck 	UV_SHOULD_ENOENT((openat(dirfd2after, "/etc/hosts", O_RDONLY) == -1), "openat");
872a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd2after, "hooray", O_RDWR|O_CREAT, 0644) == -1), "openat");
882a5fc997Sclaudio 	UV_SHOULD_SUCCEED((openat(dirfd2after, uv_file1, O_RDWR|O_CREAT, 0644) == -1), "openat");
892a5fc997Sclaudio 	UV_SHOULD_ENOENT((openat(dirfd2after, uv_file2, O_RDWR|O_CREAT, 0644) == -1), "openat");
9068ea1b06Sbeck 	return 0;
9168ea1b06Sbeck }
9268ea1b06Sbeck 
9368ea1b06Sbeck 
9468ea1b06Sbeck 
9513e6c35fSbeck static int
9642b5d727Sbeck test_open(int do_uv)
970d000527Sbeck {
980d000527Sbeck 	char filename[256];
990d000527Sbeck 	int dirfd;
1000d000527Sbeck 	int dirfd2;
1010d000527Sbeck 	int dirfd3;
1020d000527Sbeck 
1030d000527Sbeck 
10442b5d727Sbeck 	UV_SHOULD_SUCCEED(((dirfd = open("/", O_RDONLY | O_DIRECTORY)) == -1), "open");
10542b5d727Sbeck 	UV_SHOULD_SUCCEED(((dirfd2 = open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1), "open");
10642b5d727Sbeck 	if (do_uv) {
10768ea1b06Sbeck 		printf("testing open\n");
1080d000527Sbeck 		do_unveil();
10942b5d727Sbeck 		if (unveil("/tmp/alpha", uv_flags) == -1)
1100d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
11142b5d727Sbeck 		if (unveil("/tmp/bravo", uv_flags) == -1)
1120d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
11342b5d727Sbeck 		if (unveil("/tmp/charlie", uv_flags) == -1)
1140d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
11542b5d727Sbeck 		if (unveil("/tmp/delta", uv_flags) == -1)
1160d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
11742b5d727Sbeck 		if (unveil("/tmp/echo", uv_flags) == -1)
1180d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
11942b5d727Sbeck 		if (unveil("/tmp/foxtrot", uv_flags) == -1)
1200d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
12142b5d727Sbeck 		if (unveil("/tmp/golf", uv_flags) == -1)
1220d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
12342b5d727Sbeck 		if (unveil("/tmp/hotel", uv_flags) == -1)
1240d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
12542b5d727Sbeck 		if (unveil("/tmp/india", uv_flags) == -1)
1260d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
12742b5d727Sbeck 		if (unveil("/tmp/juliet", uv_flags) == -1)
1280d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
12942b5d727Sbeck 		if (unveil("/tmp/kilo", uv_flags) == -1)
1300d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
13142b5d727Sbeck 		if (unveil("/tmp/lima", uv_flags) == -1)
1320d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
13342b5d727Sbeck 		if (unveil("/tmp/money", uv_flags) == -1)
1340d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
13542b5d727Sbeck 		if (unveil("/tmp/november", uv_flags) == -1)
1360d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
13742b5d727Sbeck 		if (unveil("/tmp/oscar", uv_flags) == -1)
1380d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
13942b5d727Sbeck 		if (unveil("/tmp/papa", uv_flags) == -1)
1400d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
14142b5d727Sbeck 		if (unveil("/tmp/quebec", uv_flags) == -1)
1420d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
14342b5d727Sbeck 		if (unveil("/tmp/romeo", uv_flags) == -1)
1440d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
14542b5d727Sbeck 		if (unveil("/tmp/sierra", uv_flags) == -1)
1460d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
14742b5d727Sbeck 		if (unveil("/tmp/tango", uv_flags) == -1)
1480d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
14942b5d727Sbeck 		if (unveil("/tmp/uniform", uv_flags) == -1)
1500d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
15142b5d727Sbeck 		if (unveil("/tmp/victor", uv_flags) == -1)
1520d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
15342b5d727Sbeck 		if (unveil("/tmp/whiskey", uv_flags) == -1)
1540d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
15542b5d727Sbeck 		if (unveil("/tmp/xray", uv_flags) == -1)
1560d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
15742b5d727Sbeck 		if (unveil("/tmp/yankee", uv_flags) == -1)
1580d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
15942b5d727Sbeck 		if (unveil("/tmp/zulu", uv_flags) == -1)
1600d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
1610d000527Sbeck 	}
16242b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio rpath cpath wpath exec", NULL) == -1), "pledge");
1630d000527Sbeck 
16442b5d727Sbeck 	UV_SHOULD_ENOENT((open(uv_file2, O_RDWR) == -1), "open");
16542b5d727Sbeck 	UV_SHOULD_ENOENT(((dirfd3= open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1), "open");
1660d000527Sbeck 
16742b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
16842b5d727Sbeck 	if (!do_uv) {
1690d000527Sbeck 		/* Unlink the unveiled file and make it again */
17042b5d727Sbeck 		UV_SHOULD_SUCCEED((unlink(uv_file1) == -1), "unlink");
1712a5fc997Sclaudio 		UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR|O_CREAT, 0644) == -1), "open");
1720d000527Sbeck 	}
1730d000527Sbeck 	sleep(1);
17442b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
17542b5d727Sbeck 	UV_SHOULD_ENOENT((open(uv_file2, O_RDWR) == -1), "open");
17642b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "%s/%s", uv_dir1, "newfile");
1772a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
17842b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/%s", uv_dir1, "doubleslash");
1792a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
18042b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s//%s", uv_dir1, "doubleslash2");
1812a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
1827676bde3Sbeck 
18342b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "%s/%s", uv_dir2, "newfile");
1842a5fc997Sclaudio 	UV_SHOULD_ENOENT((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
1850d000527Sbeck 
18642b5d727Sbeck 	if (do_uv) {
1870d000527Sbeck 		printf("testing flag escalation\n");
18842b5d727Sbeck 		if (unveil(uv_file1, "x") == -1)
1890d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
19042b5d727Sbeck 		if (unveil(uv_file1, "rx") == -1)
1910d000527Sbeck 			if (errno != EPERM)
1920d000527Sbeck 				err(1, "%s:%d - unveil", __FILE__,
1930d000527Sbeck 				    __LINE__);
1940d000527Sbeck 	}
1950d000527Sbeck 	return 0;
1960d000527Sbeck }
1970d000527Sbeck 
1980d000527Sbeck static int
19942b5d727Sbeck test_opendir(int do_uv)
2007676bde3Sbeck {
2017676bde3Sbeck 	char filename[256];
20242b5d727Sbeck 	if (do_uv) {
2037676bde3Sbeck 		printf("testing opendir\n");
2047676bde3Sbeck 		do_unveil();
2057676bde3Sbeck 	}
20642b5d727Sbeck 	UV_SHOULD_SUCCEED((opendir(uv_dir1) == NULL), "opendir");
20742b5d727Sbeck 	UV_SHOULD_ENOENT((opendir(uv_dir2) == NULL), "opendir");
20842b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/.", uv_dir1);
20942b5d727Sbeck 	UV_SHOULD_SUCCEED((opendir(filename) == NULL), "opendir");
21042b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/..", uv_dir1);
211f3784bceSbeck 	UV_SHOULD_ENOENT((opendir(filename) == NULL), "opendir");
21242b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir1);
21342b5d727Sbeck 	UV_SHOULD_SUCCEED((opendir(filename) == NULL), "opendir");
21442b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/subdir/../subdir", uv_dir1);
21542b5d727Sbeck 	UV_SHOULD_SUCCEED((opendir(filename) == NULL), "opendir");
21642b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/../../%s/subdir", uv_dir1, uv_dir1);
21742b5d727Sbeck 	UV_SHOULD_SUCCEED((opendir(filename) == NULL), "opendir");
21842b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir2);
21942b5d727Sbeck 	UV_SHOULD_ENOENT((opendir(filename) == NULL), "opendir");
22042b5d727Sbeck 	UV_SHOULD_ENOENT((opendir(filename) == NULL), "opendir");
2214772489dSbeck 	(void) snprintf(filename, sizeof(filename), "%s/../..%s/subdir", uv_dir1, uv_dir2);
2224772489dSbeck 	UV_SHOULD_ENOENT((opendir(filename) == NULL), "opendir");
2234772489dSbeck 	return 0;
2244772489dSbeck }
2254772489dSbeck 
2264772489dSbeck static int
2274772489dSbeck test_realpath(int do_uv)
2284772489dSbeck {
2294772489dSbeck 	char buf[PATH_MAX];
2304772489dSbeck 	if (do_uv) {
2314772489dSbeck 		printf("testing realpath\n");
2324772489dSbeck 		do_unveil();
2334772489dSbeck 	}
2344772489dSbeck 	UV_SHOULD_SUCCEED((realpath(uv_dir1, buf) == NULL), "realpath");
2354772489dSbeck 	UV_SHOULD_ENOENT((realpath(uv_dir2, buf) == NULL), "realpath");
2367676bde3Sbeck 	return 0;
2377676bde3Sbeck }
2387676bde3Sbeck 
2397676bde3Sbeck static int
24042b5d727Sbeck test_r(int do_uv)
2410d000527Sbeck {
24242b5d727Sbeck 	if (do_uv) {
2430d000527Sbeck 		printf("testing \"r\"\n");
24442b5d727Sbeck 		if (unveil(uv_file1, "r") == -1)
2450d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2467676bde3Sbeck 		if (unveil("/", "") == -1)
2477676bde3Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2480d000527Sbeck 	}
24942b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDONLY) == -1), "open");
25042b5d727Sbeck 	UV_SHOULD_EACCES((open(uv_file1, O_RDWR) == -1), "open");
2510d000527Sbeck 	return 0;
2520d000527Sbeck }
2530d000527Sbeck 
2540d000527Sbeck static int
25542b5d727Sbeck test_rw(int do_uv)
2560d000527Sbeck {
25742b5d727Sbeck 	if (do_uv) {
2580d000527Sbeck 		printf("testing \"rw\"\n");
25942b5d727Sbeck 		if (unveil(uv_file1, "rw") == -1)
2600d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2617676bde3Sbeck 		if (unveil("/", "") == -1)
2627676bde3Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2630d000527Sbeck 	}
26442b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
26542b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDONLY) == -1), "open");
2660d000527Sbeck 	return 0;
2670d000527Sbeck }
2680d000527Sbeck 
2690d000527Sbeck static int
27042b5d727Sbeck test_x(int do_uv)
2710d000527Sbeck {
2720d000527Sbeck 	struct stat sb;
27342b5d727Sbeck 	if (do_uv) {
2740d000527Sbeck 		printf("testing \"x\"\n");
27542b5d727Sbeck 		if (unveil(uv_file1, "x") == -1)
2760d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2777676bde3Sbeck 		if (unveil("/", "") == -1)
2787676bde3Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
2790d000527Sbeck 	}
280f3784bceSbeck 	UV_SHOULD_EACCES((lstat(uv_file1, &sb) == -1), "lstat");
28142b5d727Sbeck 	UV_SHOULD_EACCES((open(uv_file1, O_RDONLY) == -1), "open");
28242b5d727Sbeck 	UV_SHOULD_EACCES((open(uv_file1, O_RDONLY) == -1), "open");
28342b5d727Sbeck 	UV_SHOULD_ENOENT((open(uv_file2, O_RDWR) == -1), "open");
2840d000527Sbeck 	return 0;
2850d000527Sbeck }
2860d000527Sbeck 
2870d000527Sbeck static int
28842b5d727Sbeck test_noflags(int do_uv)
2890d000527Sbeck {
2900d000527Sbeck 	char filename[256];
2910d000527Sbeck 
29242b5d727Sbeck 	if (do_uv) {
2930d000527Sbeck 		printf("testing clearing flags\n");
2940d000527Sbeck 		do_unveil();
2950d000527Sbeck 	}
2960d000527Sbeck 
29742b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio rpath cpath wpath exec", NULL) == -1), "pledge");
29842b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
29942b5d727Sbeck 	if (do_uv) {
30042b5d727Sbeck 		if (unveil(uv_dir1, "") == -1)
3010d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
3020d000527Sbeck 	}
30342b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "%s/%s", uv_dir1, "noflagsiamboned");
3042a5fc997Sclaudio 	UV_SHOULD_ENOENT((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
30542b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
3060d000527Sbeck 	return 0;
3070d000527Sbeck }
3080d000527Sbeck 
3090d000527Sbeck 
3100d000527Sbeck static int
31142b5d727Sbeck test_drounveil(int do_uv)
3120d000527Sbeck {
31342b5d727Sbeck 	if (do_uv) {
3140d000527Sbeck 		printf("(testing unveil after pledge)\n");
3150d000527Sbeck 		do_unveil();
3160d000527Sbeck 	}
3170d000527Sbeck 
31842b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio rpath cpath wpath exec", NULL) == -1), "pledge");
3190d000527Sbeck 
32042b5d727Sbeck 	if (do_uv) {
3210d000527Sbeck 		do_unveil();
3220d000527Sbeck 	}
32342b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio rpath cpath wpath", NULL) == -1), "pledge");
3240d000527Sbeck 
32542b5d727Sbeck 	UV_SHOULD_ENOENT((open(uv_file2, O_RDWR) == -1), "open");
32642b5d727Sbeck 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR) == -1), "open");
3270d000527Sbeck 	return 0;
3280d000527Sbeck }
3290d000527Sbeck 
3300d000527Sbeck static int
33142b5d727Sbeck test_unlink(int do_uv)
3320d000527Sbeck {
3330d000527Sbeck 	char filename1[256];
3340d000527Sbeck 	char filename2[256];
3350d000527Sbeck 	char filename3[] = "/tmp/nukeme.XXXXXX";
3360d000527Sbeck 	int fd;
3370d000527Sbeck 
33842b5d727Sbeck 	(void) snprintf(filename1, sizeof(filename1), "%s/%s", uv_dir1,
3390d000527Sbeck 	    "nukeme");
34042b5d727Sbeck 	(void) snprintf(filename2, sizeof(filename2), "%s/%s", uv_dir2,
3410d000527Sbeck 	    "nukeme");
3422a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
3432a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename2, O_RDWR|O_CREAT, 0644) == -1), "open");
3440d000527Sbeck 	if ((fd = mkstemp(filename3)) == -1)
3450d000527Sbeck 		err(1, "%s:%d - mkstemp", __FILE__, __LINE__);
34642b5d727Sbeck 	if (do_uv) {
3470d000527Sbeck 		printf("testing unlink\n");
3480d000527Sbeck 		do_unveil();
3490d000527Sbeck 		if (unveil(filename3, "rw") == -1)
3500d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
3510d000527Sbeck 	}
3520d000527Sbeck 
35342b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio fattr rpath cpath wpath", NULL) == -1),
3540d000527Sbeck 	    "pledge");
35542b5d727Sbeck 	UV_SHOULD_SUCCEED((unlink(filename1) == -1), "unlink");
35642b5d727Sbeck 	UV_SHOULD_ENOENT((unlink(filename2) == -1), "unlink");
35742b5d727Sbeck 	UV_SHOULD_EACCES((unlink(filename3) == -1), "unlink");
3580d000527Sbeck 	return 0;
3590d000527Sbeck }
3600d000527Sbeck 
3610d000527Sbeck static int
36242b5d727Sbeck test_link(int do_uv)
3630d000527Sbeck {
3640d000527Sbeck 	char filename[256];
3650d000527Sbeck 	char filename2[256];
3660d000527Sbeck 
36742b5d727Sbeck 	if (do_uv) {
3680d000527Sbeck 		printf("testing link\n");
3690d000527Sbeck 		do_unveil();
3700d000527Sbeck 	}
3710d000527Sbeck 
37242b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio fattr rpath cpath wpath", NULL) == -1),
3730d000527Sbeck 	    "pledge");
37442b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "%s/%s", uv_dir1,
37542b5d727Sbeck 	    "linkuv1");
37642b5d727Sbeck 	(void) snprintf(filename2, sizeof(filename2), "%s/%s", uv_dir2,
37742b5d727Sbeck 	    "linkuv2");
3780d000527Sbeck 	unlink(filename);
3790d000527Sbeck 	unlink(filename2);
38042b5d727Sbeck 	UV_SHOULD_SUCCEED((link(uv_file1, filename) == -1), "link");
3810d000527Sbeck 	unlink(filename);
38242b5d727Sbeck 	UV_SHOULD_ENOENT((link(uv_file2, filename) == -1), "link");
38342b5d727Sbeck 	UV_SHOULD_ENOENT((link(uv_file1, filename2) == -1), "link");
38442b5d727Sbeck 	if (do_uv) {
3850d000527Sbeck 		printf("testing link without O_CREAT\n");
3860d000527Sbeck 		if (unveil(filename, "rw") == -1)
3870d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
3880d000527Sbeck 
3890d000527Sbeck 	}
39042b5d727Sbeck 	UV_SHOULD_EACCES((link(uv_file1, filename) == -1), "link");
3910d000527Sbeck 	unlink(filename);
3920d000527Sbeck 
3930d000527Sbeck 	return 0;
3940d000527Sbeck }
3950d000527Sbeck 
3960d000527Sbeck 
3970d000527Sbeck static int
39842b5d727Sbeck test_chdir(int do_uv)
3990d000527Sbeck {
40042b5d727Sbeck 	if (do_uv) {
4010d000527Sbeck 		printf("testing chdir\n");
402f195f92eSbeck 		do_unveil2();
4030d000527Sbeck 	}
4040d000527Sbeck 
40542b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
406f195f92eSbeck 	UV_SHOULD_ENOENT((chdir(uv_dir2) == -1), "chdir");
40742b5d727Sbeck 	UV_SHOULD_SUCCEED((chdir(uv_dir1) == -1), "chdir");
40842b5d727Sbeck 	UV_SHOULD_ENOENT((chdir(uv_dir2) == -1), "chdir");
4090d000527Sbeck 
4100d000527Sbeck 	return 0;
4110d000527Sbeck }
4129a5a31c7Srobert 
413f195f92eSbeck static int
414f195f92eSbeck test_parent_dir(int do_uv)
415f195f92eSbeck {
416f195f92eSbeck 	char filename[255];
417f195f92eSbeck 	if (do_uv) {
418585157b0Sbeck 		printf("testing parent dir\n");
419f195f92eSbeck 		do_unveil2();
420f195f92eSbeck 	} else {
421f195f92eSbeck 		(void) snprintf(filename, sizeof(filename), "/%s/doof", uv_dir1);
422f195f92eSbeck 		UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
423f195f92eSbeck 		(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir2", uv_dir1);
424f195f92eSbeck 		UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
425f195f92eSbeck 		(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1", uv_dir1);
426f195f92eSbeck 		UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
4279cf24395Sbeck 		(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1/poop", uv_dir1);
428585157b0Sbeck 		UV_SHOULD_SUCCEED((open(filename, O_RDWR|O_CREAT, 0644) == -1), "open");
4299cf24395Sbeck 		(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1/link", uv_dir1);
4309cf24395Sbeck 		UV_SHOULD_SUCCEED((symlink("../subdir1/poop", filename) == -1), "symlink");
431f195f92eSbeck 	}
432f195f92eSbeck 	sleep(1);
4339cf24395Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1/link", uv_dir1);
4349cf24395Sbeck 	UV_SHOULD_SUCCEED((access(filename, R_OK) == -1), "access");
435585157b0Sbeck 	(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1/poop", uv_dir1);
436585157b0Sbeck 	UV_SHOULD_SUCCEED((access(filename, R_OK) == -1), "access");
437f195f92eSbeck 	UV_SHOULD_SUCCEED((chdir(uv_dir1) == -1), "chdir");
438f195f92eSbeck 	(void) snprintf(filename, sizeof(filename), "/%s/doof/subdir1", uv_dir1);
439f195f92eSbeck 	UV_SHOULD_SUCCEED((chdir(filename) == -1), "chdir");
440585157b0Sbeck 	UV_SHOULD_SUCCEED((access("poop", R_OK) == -1), "access");
441f195f92eSbeck 	UV_SHOULD_SUCCEED((chdir("../subdir2") == -1), "chdir");
442f195f92eSbeck 	UV_SHOULD_SUCCEED((chdir("../subdir1") == -1), "chdir");
443585157b0Sbeck 	UV_SHOULD_SUCCEED((chdir(filename) == -1), "chdir");
444585157b0Sbeck 	UV_SHOULD_SUCCEED((chdir("../../doof/subdir2") == -1), "chdir");
445585157b0Sbeck 	UV_SHOULD_SUCCEED((chdir("../../doof/subdir1") == -1), "chdir");
446585157b0Sbeck 	UV_SHOULD_SUCCEED((chdir("../../doof/subdir2") == -1), "chdir");
447585157b0Sbeck 	UV_SHOULD_SUCCEED((chdir("../../doof/subdir1") == -1), "chdir");
448585157b0Sbeck 	UV_SHOULD_SUCCEED((access("poop", R_OK) == -1), "access");
449585157b0Sbeck 	UV_SHOULD_SUCCEED((access("../subdir1/poop", R_OK) == -1), "access");
45068ea1b06Sbeck 	UV_SHOULD_ENOENT((chdir("../../..") == -1), "chdir");
451585157b0Sbeck 	UV_SHOULD_ENOENT((chdir(uv_dir2) == -1), "chdir");
452585157b0Sbeck 	return(0);
453f195f92eSbeck }
4540d000527Sbeck 
4550d000527Sbeck static int
45642b5d727Sbeck test_rename(int do_uv)
4570d000527Sbeck {
4580d000527Sbeck 	char filename1[256];
4590d000527Sbeck 	char filename2[256];
4600d000527Sbeck 	char rfilename1[256];
4610d000527Sbeck 	char rfilename2[256];
4620d000527Sbeck 	int dirfd1, dirfd2;
4630d000527Sbeck 
46442b5d727Sbeck 	if ((dirfd1 = open(uv_dir1, O_RDONLY | O_DIRECTORY)) == -1)
4650d000527Sbeck 		err(1, "%s:%d - open of dir1", __FILE__, __LINE__);
46642b5d727Sbeck 	if ((dirfd2 = open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1)
4670d000527Sbeck 		err(1, "%s:%d - open of dir2", __FILE__, __LINE__);
46842b5d727Sbeck 	(void) snprintf(filename1, sizeof(filename1), "%s/%s", uv_dir1,
4690d000527Sbeck 	    "file1");
4702a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
47142b5d727Sbeck 	(void) snprintf(filename2, sizeof(filename2), "%s/%s", uv_dir2,
4720d000527Sbeck 	    "file2");
4732a5fc997Sclaudio         UV_SHOULD_SUCCEED((open(filename2, O_RDWR|O_CREAT, 0644) == -1), "open");
47442b5d727Sbeck 	(void) snprintf(rfilename1, sizeof(rfilename1), "%s/%s", uv_dir1,
4750d000527Sbeck 	    "rfile1");
47642b5d727Sbeck 	(void) snprintf(rfilename2, sizeof(rfilename2), "%s/%s", uv_dir2,
4770d000527Sbeck 	    "rfile2");
47842b5d727Sbeck 	if (do_uv) {
4790d000527Sbeck 		printf("testing rename\n");
4800d000527Sbeck 		do_unveil();
4810d000527Sbeck 	}
4820d000527Sbeck 
48342b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath wpath cpath", NULL) == -1),
4840d000527Sbeck 	    "pledge");
48542b5d727Sbeck 	UV_SHOULD_SUCCEED((rename(filename1, rfilename1) == -1), "rename");
48642b5d727Sbeck 	UV_SHOULD_ENOENT((rename(filename2, rfilename2) == -1), "rename");
4872a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
48842b5d727Sbeck 	UV_SHOULD_ENOENT((rename(filename1, rfilename2) == -1), "rename");
4892a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
49042b5d727Sbeck 	UV_SHOULD_ENOENT((rename(filename1, uv_file2) == -1), "rename");
4912a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
49242b5d727Sbeck 	UV_SHOULD_ENOENT((renameat(dirfd1, "file1", dirfd2, "rfile2") == -1),
4930d000527Sbeck 	    "renameat");
4942a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(filename1, O_RDWR|O_CREAT, 0644) == -1), "open");
49542b5d727Sbeck 	UV_SHOULD_ENOENT((renameat(dirfd1, "file1", dirfd2, rfilename2) == -1),
4960d000527Sbeck 	    "renameat");
4970d000527Sbeck 
4980d000527Sbeck 	return (0);
4990d000527Sbeck }
5000d000527Sbeck 
5010d000527Sbeck 
5020d000527Sbeck static int
50342b5d727Sbeck test_access(int do_uv)
5040d000527Sbeck {
50542b5d727Sbeck 	if (do_uv) {
5060d000527Sbeck 		printf("testing access\n");
5070d000527Sbeck 		do_unveil();
5080d000527Sbeck 	}
5090d000527Sbeck 
5109ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((access(uv_file1, R_OK) == -1), "access");
5119ad0f3d4Sbeck 	UV_SHOULD_ENOENT((access(uv_file2, R_OK) == -1), "access");
5124772489dSbeck 	UV_SHOULD_ENOENT((access("/etc/passwd", R_OK) == -1), "access");
5139ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((access(uv_dir1, R_OK) == -1), "access");
5149ad0f3d4Sbeck 	UV_SHOULD_ENOENT((access(uv_dir2, R_OK) == -1), "access");
515f3784bceSbeck 	UV_SHOULD_ENOENT((access("/", R_OK) == -1), "access");
5169ad0f3d4Sbeck 	UV_SHOULD_ENOENT((access("/home", F_OK) == -1), "access");
5179ad0f3d4Sbeck 
51842b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
51942b5d727Sbeck 	UV_SHOULD_SUCCEED((access(uv_file1, R_OK) == -1), "access");
52042b5d727Sbeck 	UV_SHOULD_ENOENT((access(uv_file2, R_OK) == -1), "access");
52142b5d727Sbeck 	UV_SHOULD_SUCCEED((access(uv_dir1, R_OK) == -1), "access");
52242b5d727Sbeck 	UV_SHOULD_ENOENT((access(uv_dir2, R_OK) == -1), "access");
523f3784bceSbeck 	UV_SHOULD_ENOENT((access("/", R_OK) == -1), "access");
5249ad0f3d4Sbeck 	UV_SHOULD_ENOENT((access("/home", F_OK) == -1), "access");
5250d000527Sbeck 
5260d000527Sbeck 	return 0;
5270d000527Sbeck }
5280d000527Sbeck 
5290d000527Sbeck static int
53042b5d727Sbeck test_chflags(int do_uv)
5310d000527Sbeck {
53242b5d727Sbeck 	if (do_uv) {
5330d000527Sbeck 		printf("testing chflags\n");
5340d000527Sbeck 		do_unveil();
5350d000527Sbeck 	}
5360d000527Sbeck 
53742b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
53842b5d727Sbeck 	UV_SHOULD_SUCCEED((chflags(uv_file1, UF_NODUMP) == -1), "chflags");
53942b5d727Sbeck 	UV_SHOULD_ENOENT((chflags(uv_file2, UF_NODUMP) == -1), "chflags");
5400d000527Sbeck 
5410d000527Sbeck 	return 0;
5420d000527Sbeck }
5430d000527Sbeck 
5440d000527Sbeck static int
54542b5d727Sbeck test_stat(int do_uv)
5460d000527Sbeck {
54742b5d727Sbeck 	if (do_uv) {
5480d000527Sbeck 		printf("testing stat\n");
5490d000527Sbeck 		do_unveil();
5500d000527Sbeck 	}
5510d000527Sbeck 	struct stat sb;
5520d000527Sbeck 
55342b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
55442b5d727Sbeck 	UV_SHOULD_SUCCEED((stat(uv_file1, &sb) == -1), "stat");
555d493af70Sbeck 	UV_SHOULD_ENOENT((stat(uv_file2, &sb) == -1), "stat");
55642b5d727Sbeck 	UV_SHOULD_SUCCEED((stat(uv_dir1, &sb) == -1), "stat");
5574772489dSbeck 	UV_SHOULD_ENOENT((stat(uv_dir2, &sb) == -1), "stat");
558f3784bceSbeck 	UV_SHOULD_ENOENT((stat("/", &sb) == -1), "stat");
5590d000527Sbeck 
5600d000527Sbeck 	return 0;
5610d000527Sbeck }
5620d000527Sbeck 
5630d000527Sbeck static int
564ba253c9bSbeck test_stat2(int do_uv)
565ba253c9bSbeck {
566ba253c9bSbeck 	if (do_uv) {
5676ba149ccSphessler 		printf("testing stat components to nonexistent \"rw\"\n");
5686ba149ccSphessler 		if (unveil("/usr/share/man/nonexistent", "rw") == -1)
569ba253c9bSbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
570ba253c9bSbeck 	}
571ba253c9bSbeck 	struct stat sb;
572ba253c9bSbeck 
573ba253c9bSbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
574f3784bceSbeck 	UV_SHOULD_ENOENT((stat("/", &sb) == -1), "stat");
575f3784bceSbeck 	UV_SHOULD_ENOENT((stat("/usr", &sb) == -1), "stat");
576f3784bceSbeck 	UV_SHOULD_ENOENT((stat("/usr/share", &sb) == -1), "stat");
577f3784bceSbeck 	UV_SHOULD_ENOENT((stat("/usr/share/man", &sb) == -1), "stat");
5786ba149ccSphessler 	UV_SHOULD_ENOENT((stat("/usr/share/man/nonexistent", &sb) == -1), "stat");
579ba253c9bSbeck 	return 0;
580ba253c9bSbeck }
581ba253c9bSbeck 
582ba253c9bSbeck static int
58342b5d727Sbeck test_statfs(int do_uv)
5840d000527Sbeck {
58542b5d727Sbeck 	if (do_uv) {
5860d000527Sbeck 		printf("testing statfs\n");
5870d000527Sbeck 		do_unveil();
5880d000527Sbeck 	}
5890d000527Sbeck 	struct statfs sb;
5900d000527Sbeck 
5919ad0f3d4Sbeck 
5929ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs("/home", &sb) == -1), "statfs");
5939ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs("/", &sb) == -1), "statfs");
5949ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_file1, &sb) == -1), "statfs");
5959ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_file2, &sb) == -1), "statfs");
5969ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_dir1, &sb) == -1), "statfs");
5979ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_dir2, &sb) == -1), "statfs");
59842b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
59942b5d727Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_file1, &sb) == -1), "statfs");
6009ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_file2, &sb) == -1), "statfs");
60142b5d727Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_dir1, &sb) == -1), "statfs");
6029ad0f3d4Sbeck 	UV_SHOULD_SUCCEED((statfs(uv_dir2, &sb) == -1), "statfs");
6030d000527Sbeck 
6040d000527Sbeck 	return 0;
6050d000527Sbeck }
6060d000527Sbeck 
6070d000527Sbeck static int
60842b5d727Sbeck test_symlink(int do_uv)
6090d000527Sbeck {
6100d000527Sbeck 	char filename[256];
6110d000527Sbeck 	char filename2[256];
6120d000527Sbeck 	char buf[256];
6130d000527Sbeck 	struct stat sb;
6140d000527Sbeck 
61542b5d727Sbeck 	if (do_uv) {
6160d000527Sbeck 		printf("testing symlink and lstat and readlink\n");
6170d000527Sbeck 		do_unveil();
6180d000527Sbeck 	}
6190d000527Sbeck 
62042b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio fattr rpath cpath wpath", NULL) == -1),
6210d000527Sbeck 	    "pledge");
62242b5d727Sbeck 	(void) snprintf(filename, sizeof(filename), "%s/%s", uv_dir1,
62342b5d727Sbeck 	    "slinkuv1");
62442b5d727Sbeck 	(void) snprintf(filename2, sizeof(filename2), "%s/%s", uv_dir2,
62542b5d727Sbeck 	    "slinkuv2");
6260d000527Sbeck 	unlink(filename);
6270d000527Sbeck 	unlink(filename2);
62842b5d727Sbeck 	UV_SHOULD_SUCCEED((symlink(uv_file1, filename) == -1), "symlink");
62942b5d727Sbeck 	UV_SHOULD_SUCCEED((lstat(filename, &sb) == -1), "lstat");
63042b5d727Sbeck 	UV_SHOULD_SUCCEED((lstat(uv_file1, &sb) == -1), "lstat");
63142b5d727Sbeck 	UV_SHOULD_SUCCEED((readlink(filename, buf, sizeof(buf)) == -1), "readlink");
6320d000527Sbeck 	unlink(filename);
63342b5d727Sbeck 	UV_SHOULD_SUCCEED((symlink(uv_file2, filename) == -1), "symlink");
63442b5d727Sbeck 	UV_SHOULD_SUCCEED((lstat(filename, &sb) == -1), "lstat");
63542b5d727Sbeck 	UV_SHOULD_SUCCEED((readlink(filename, buf, sizeof(buf)) == -1), "readlink");
636d493af70Sbeck 	UV_SHOULD_ENOENT((lstat(uv_file2, &sb) == -1), "lstat");
63742b5d727Sbeck 	UV_SHOULD_ENOENT((symlink(uv_file1, filename2) == -1), "symlink");
63842b5d727Sbeck 	UV_SHOULD_ENOENT((readlink(filename2, buf, sizeof(buf)) == -1), "readlink");
6390d000527Sbeck 	unlink(filename);
6400d000527Sbeck 
64142b5d727Sbeck 	if (do_uv) {
6420d000527Sbeck 		printf("testing symlink with \"rw\"\n");
6430d000527Sbeck 		if (unveil(filename, "rw") == -1)
6440d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
6450d000527Sbeck 	}
64642b5d727Sbeck 	UV_SHOULD_EACCES((symlink(uv_file1, filename) == -1), "symlink");
6470d000527Sbeck 
6480d000527Sbeck 	return 0;
6490d000527Sbeck }
6500d000527Sbeck 
6510d000527Sbeck static int
65242b5d727Sbeck test_chmod(int do_uv)
6530d000527Sbeck {
65442b5d727Sbeck 	if (do_uv) {
6550d000527Sbeck 		printf("testing chmod\n");
6560d000527Sbeck 		do_unveil();
6570d000527Sbeck 	}
6582a042debSbeck 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath unveil", NULL) == -1), "pledge");
65942b5d727Sbeck 	UV_SHOULD_SUCCEED((chmod(uv_file1, S_IRWXU) == -1), "chmod");
66042b5d727Sbeck 	UV_SHOULD_ENOENT((chmod(uv_file2, S_IRWXU) == -1), "chmod");
66142b5d727Sbeck 	UV_SHOULD_SUCCEED((chmod(uv_dir1, S_IRWXU) == -1), "chmod");
66242b5d727Sbeck 	UV_SHOULD_ENOENT((chmod(uv_dir2, S_IRWXU) == -1), "chmod");
6632a042debSbeck 	if (do_uv) {
6642a042debSbeck 		printf("testing chmod should fail for read\n");
6652a042debSbeck 		if (unveil(uv_file1, "r") == -1)
6662a042debSbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
6672a042debSbeck 	}
6682a042debSbeck 	UV_SHOULD_EACCES((chmod(uv_file1, S_IRWXU) == -1), "chmod");
6690d000527Sbeck 	return 0;
6700d000527Sbeck }
67113e6c35fSbeck 
67213e6c35fSbeck 
67313e6c35fSbeck static int
67413e6c35fSbeck test_fork_body(int do_uv)
67513e6c35fSbeck {
6762a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open(uv_file1, O_RDWR|O_CREAT, 0644) == -1), "open after fork");
67713e6c35fSbeck 	UV_SHOULD_SUCCEED((opendir(uv_dir1) == NULL), "opendir after fork");
67813e6c35fSbeck 	UV_SHOULD_ENOENT((opendir(uv_dir2) == NULL), "opendir after fork");
6792a5fc997Sclaudio 	UV_SHOULD_ENOENT((open(uv_file2, O_RDWR|O_CREAT, 0644) == -1), "open after fork");
68013e6c35fSbeck 	return 0;
68113e6c35fSbeck }
682*2c5685b9Santon 
68313e6c35fSbeck static int
684*2c5685b9Santon test_fork(int do_uv)
68513e6c35fSbeck {
68613e6c35fSbeck 	printf("testing fork inhertiance\n");
68713e6c35fSbeck 	do_unveil();
68813e6c35fSbeck 	return runcompare_internal(test_fork_body, 0);
68913e6c35fSbeck }
69013e6c35fSbeck 
6910d000527Sbeck static int
69242b5d727Sbeck test_exec(int do_uv)
6930d000527Sbeck {
6940d000527Sbeck 	char *argv[] = {"/usr/bin/true", NULL};
6950d000527Sbeck 	extern char **environ;
69642b5d727Sbeck 	if (do_uv) {
6970d000527Sbeck 		printf("testing execve with \"x\"\n");
6980d000527Sbeck 		if (unveil("/usr/bin/true", "x") == -1)
6990d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7005cdd3eb0Sbeck 		/* dynamic linking requires this */
7015cdd3eb0Sbeck 		if (unveil("/usr/lib", "r") == -1)
7025cdd3eb0Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7035cdd3eb0Sbeck 		if (unveil("/usr/libexec/ld.so", "r") == -1)
7045cdd3eb0Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7050d000527Sbeck 	}
70642b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio fattr exec", NULL) == -1), "pledge");
70742b5d727Sbeck 	UV_SHOULD_SUCCEED((execve(argv[0], argv, environ) == -1), "execve");
7080d000527Sbeck 	return 0;
7090d000527Sbeck }
71013e6c35fSbeck 
7110d000527Sbeck static int
71242b5d727Sbeck test_exec2(int do_uv)
7130d000527Sbeck {
7140d000527Sbeck 	char *argv[] = {"/usr/bin/true", NULL};
7150d000527Sbeck 	extern char **environ;
71642b5d727Sbeck 	if (do_uv) {
7170d000527Sbeck 		printf("testing execve with \"rw\"\n");
7180d000527Sbeck 		if (unveil("/usr/bin/true", "rw") == -1)
7190d000527Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7205cdd3eb0Sbeck 		/* dynamic linking requires this */
7215cdd3eb0Sbeck 		if (unveil("/usr/lib", "r") == -1)
7225cdd3eb0Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7235cdd3eb0Sbeck 		if (unveil("/usr/libexec/ld.so", "r") == -1)
7245cdd3eb0Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
7250d000527Sbeck 	}
72642b5d727Sbeck 	UV_SHOULD_SUCCEED((pledge("unveil stdio fattr exec", NULL) == -1), "pledge");
72742b5d727Sbeck 	UV_SHOULD_EACCES((execve(argv[0], argv, environ) == -1), "execve");
7280d000527Sbeck 	return 0;
7290d000527Sbeck }
7300d000527Sbeck 
73119e2994eSbeck static int
73219e2994eSbeck test_slash(int do_uv)
73319e2994eSbeck {
73419e2994eSbeck 	extern char **environ;
73519e2994eSbeck 	if (do_uv) {
736ff8da2f7Sbeck 		printf("testing unveil(\"/\")\n");
73719e2994eSbeck 		if (unveil("/bin/sh", "x") == -1)
73819e2994eSbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
73919e2994eSbeck 		if (unveil("/", "r") == -1)
74019e2994eSbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
74119e2994eSbeck 	}
74219e2994eSbeck 	return 0;
74319e2994eSbeck }
74419e2994eSbeck 
7459a5a31c7Srobert static int
746ff8da2f7Sbeck test_dot(int do_uv)
747ff8da2f7Sbeck {
748ff8da2f7Sbeck 	extern char **environ;
749ff8da2f7Sbeck 	if (do_uv) {
750bd7bdf35Sbeck 		printf("testing dot(\".\")\n");
751ff8da2f7Sbeck 		if (unveil(".", "rwxc") == -1)
752ff8da2f7Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
753bd7bdf35Sbeck 		if ((unlink(".") == -1) && errno != EPERM)
754bd7bdf35Sbeck 			err(1, "%s:%d - unlink", __FILE__, __LINE__);
755bd7bdf35Sbeck 		printf("testing dot flags(\".\")\n");
756bd7bdf35Sbeck 		if (unveil(".", "r") == -1)
757bd7bdf35Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
758bd7bdf35Sbeck 		if ((unlink(".") == -1) && errno != EACCES)
759bd7bdf35Sbeck 			warn("%s:%d - unlink", __FILE__, __LINE__);
760ff8da2f7Sbeck 	}
761ff8da2f7Sbeck 	return 0;
762ff8da2f7Sbeck }
763ff8da2f7Sbeck 
764ff8da2f7Sbeck static int
7659a5a31c7Srobert test_bypassunveil(int do_uv)
7669a5a31c7Srobert {
7679a5a31c7Srobert 	if (do_uv) {
7689a5a31c7Srobert 		printf("testing BYPASSUNVEIL\n");
7699a5a31c7Srobert 		do_unveil2();
7709a5a31c7Srobert 	}
7715cdd3eb0Sbeck 	char filename3[] = "/tmp/nukeme.XXXXXX";
7729a5a31c7Srobert 
7735cdd3eb0Sbeck 	UV_SHOULD_SUCCEED((pledge("stdio tmppath", NULL) == -1), "pledge");
7745cdd3eb0Sbeck 	UV_SHOULD_SUCCEED((mkstemp(filename3) == -1), "mkstemp");
7759a5a31c7Srobert 
7769a5a31c7Srobert 	return 0;
7779a5a31c7Srobert }
7789a5a31c7Srobert 
7793765a54cSbeck 
7803765a54cSbeck static int
7813765a54cSbeck test_dotdotup(int do_uv)
7823765a54cSbeck {
7832a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open("/tmp/hello", O_RDWR|O_CREAT, 0644) == -1), "open");
7843765a54cSbeck 	if (do_uv) {
7853765a54cSbeck 		printf("testing dotdotup\n");
7863765a54cSbeck 		do_unveil2();
7873765a54cSbeck 	}
7883765a54cSbeck 	if ((chdir(uv_dir1) == -1)) {
7893765a54cSbeck 		err(1, "chdir");
7903765a54cSbeck 	}
7912a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open("./derp", O_RDWR|O_CREAT, 0644) == -1), "open");
7922a5fc997Sclaudio 	UV_SHOULD_SUCCEED((open("derp", O_RDWR|O_CREAT, 0644) == -1), "open");
7932a5fc997Sclaudio 	UV_SHOULD_ENOENT((open("../hello", O_RDWR|O_CREAT, 0644) == -1), "open");
7942a5fc997Sclaudio 	UV_SHOULD_ENOENT((open(".././hello", O_RDWR|O_CREAT, 0644) == -1), "open");
7953765a54cSbeck 	return 0;
7963765a54cSbeck }
7973765a54cSbeck 
7986fd26cb2Sbeck static int
7996fd26cb2Sbeck test_kn(int do_uv)
8006fd26cb2Sbeck {
8016fd26cb2Sbeck 	if (do_uv) {
8026fd26cb2Sbeck 		printf("testing read only with one writeable file\n");
8036fd26cb2Sbeck 		if (unveil("/", "r") == -1)
8046fd26cb2Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
8056fd26cb2Sbeck 		if (unveil("/dev/null", "rw") == -1)
8066fd26cb2Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
8076fd26cb2Sbeck 	}
8086fd26cb2Sbeck 	UV_SHOULD_SUCCEED((open("/dev/null", O_RDWR) == -1), "open");
8096fd26cb2Sbeck 	UV_SHOULD_SUCCEED((open("/dev/zero", O_RDONLY) == -1), "open");
8101939e486Sbeck 	UV_SHOULD_EACCES((open("/dev/zero", O_RDWR) == -1), "open");
8116fd26cb2Sbeck 	return 0;
8126fd26cb2Sbeck }
8136fd26cb2Sbeck 
8146fd26cb2Sbeck 
81505b775d5Sbeck static int
81605b775d5Sbeck test_pathdiscover(int do_uv)
81705b775d5Sbeck {
81805b775d5Sbeck 	struct stat sb;
81905b775d5Sbeck 	if (do_uv) {
82005b775d5Sbeck 		printf("testing path discovery\n");
82105b775d5Sbeck 		if (unveil("/usr/share/man", "rx") == -1)
82205b775d5Sbeck 			err(1, "%s:%d - unveil", __FILE__, __LINE__);
82305b775d5Sbeck 	}
82405b775d5Sbeck 	UV_SHOULD_SUCCEED((lstat("/usr/share/man", &sb) == -1), "lstat");
82505b775d5Sbeck 	UV_SHOULD_SUCCEED((lstat("/usr/share/man/../../share/man", &sb) == -1), "lstat");
82605b775d5Sbeck 	/* XXX XXX XXX This should fail */
82705b775d5Sbeck 	UV_SHOULD_SUCCEED((lstat("/usr/share/man/../../local/../share/man", &sb) == -1), "lstat");
82805b775d5Sbeck 	return 0;
82905b775d5Sbeck }
83005b775d5Sbeck 
8312f30fa3dSclaudio static int
8322f30fa3dSclaudio test_fchdir(int do_uv)
8332f30fa3dSclaudio {
8342f30fa3dSclaudio 	int fd2, fd;
8352f30fa3dSclaudio 
8362f30fa3dSclaudio 	UV_SHOULD_SUCCEED(((fd2 = open(uv_dir2, O_RDONLY | O_DIRECTORY)) == -1), "open");
8372f30fa3dSclaudio 
8382f30fa3dSclaudio 	if (do_uv) {
8392f30fa3dSclaudio 		printf("testing fchdir\n");
8402f30fa3dSclaudio 		do_unveil2();
8412f30fa3dSclaudio 	}
8422f30fa3dSclaudio 
8432f30fa3dSclaudio 	UV_SHOULD_SUCCEED((pledge("stdio fattr rpath", NULL) == -1), "pledge");
8442f30fa3dSclaudio 	UV_SHOULD_SUCCEED((chdir(uv_dir1) == -1), "chdir");
8452f30fa3dSclaudio 	UV_SHOULD_SUCCEED((fchdir(fd2) == -1), "fchdir");
8462f30fa3dSclaudio 	UV_SHOULD_ENOENT((fd = (open("subdir", O_RDONLY | O_DIRECTORY)) == -1), "open");
8472f30fa3dSclaudio 
8482f30fa3dSclaudio 	return 0;
8492f30fa3dSclaudio }
85005b775d5Sbeck 
851d903b886Sclaudio static int
852d903b886Sclaudio test_fork_locked(int do_uv)
853d903b886Sclaudio {
854d903b886Sclaudio 	int status;
855d903b886Sclaudio 	pid_t pid;
856d903b886Sclaudio 
857d903b886Sclaudio 	if (do_uv) {
858d903b886Sclaudio 		printf("testing unveil locked fork\n");
859d903b886Sclaudio 		unveil(NULL, NULL);
860d903b886Sclaudio 	}
861d903b886Sclaudio 
862d903b886Sclaudio 	pid = fork();
863d903b886Sclaudio 	if (pid == 0) {
864d903b886Sclaudio 		UV_SHOULD_EPERM((unveil("/", "rwx") == -1), "unveil");
865d903b886Sclaudio 		exit(0);
866d903b886Sclaudio 	}
867d903b886Sclaudio 
868d903b886Sclaudio 	status = 0;
869d903b886Sclaudio 	waitpid(pid, &status, 0);
870d903b886Sclaudio 	if (WIFSIGNALED(status))
8716822f9c8Santon 		errx(1, "child exited with signal %d", WTERMSIG(status));
872d903b886Sclaudio 	if (WEXITSTATUS(status) == 0)
873d903b886Sclaudio 		return 0;
874d903b886Sclaudio 	else
875d903b886Sclaudio 		return 1;
876d903b886Sclaudio }
877d903b886Sclaudio 
878748ad6d0Sclaudio static int
879748ad6d0Sclaudio test_intermediate_node(int do_uv)
880748ad6d0Sclaudio {
881748ad6d0Sclaudio 	struct stat st;
882748ad6d0Sclaudio 
883748ad6d0Sclaudio 	if (do_uv) {
884748ad6d0Sclaudio 		printf("testing unveil on intermediate node\n");
885748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil("/", "r") == -1), "unveil");
886748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil("/usr/bin/id", "rx") == -1),
887748ad6d0Sclaudio 		    "unveil");
888748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil(NULL, NULL) == -1), "unveil");
889748ad6d0Sclaudio 	}
890748ad6d0Sclaudio 
891748ad6d0Sclaudio 	UV_SHOULD_SUCCEED((stat("/usr/bin", &st) == -1), "stat");
892748ad6d0Sclaudio 	return 0;
893748ad6d0Sclaudio }
894748ad6d0Sclaudio 
895748ad6d0Sclaudio static int
896748ad6d0Sclaudio test_noaccess_node(int do_uv)
897748ad6d0Sclaudio {
898748ad6d0Sclaudio 	struct stat st;
899748ad6d0Sclaudio 
900748ad6d0Sclaudio 	if (do_uv) {
901748ad6d0Sclaudio 		printf("testing unveil on noaccess node\n");
902748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil("/", "r") == -1), "unveil");
903748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil("/usr/bin/id", "rx") == -1),
904748ad6d0Sclaudio 		    "unveil");
905748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil("/usr/bin", "") == -1), "unveil");
906748ad6d0Sclaudio 		UV_SHOULD_SUCCEED((unveil(NULL, NULL) == -1), "unveil");
907748ad6d0Sclaudio 	}
908748ad6d0Sclaudio 
909748ad6d0Sclaudio 	UV_SHOULD_ENOENT((stat("/usr/bin", &st) == -1), "stat");
910748ad6d0Sclaudio 	return 0;
911748ad6d0Sclaudio }
912748ad6d0Sclaudio 
9130d000527Sbeck int
9140d000527Sbeck main(int argc, char *argv[])
9150d000527Sbeck {
916b749d6b5Santon 	int failures = 0;
9170d000527Sbeck 
918b749d6b5Santon 	test_setup();
9190d000527Sbeck 
9200d000527Sbeck 	failures += runcompare(test_open);
92168ea1b06Sbeck 	failures += runcompare(test_openat);
9227676bde3Sbeck 	failures += runcompare(test_opendir);
9230d000527Sbeck 	failures += runcompare(test_noflags);
92442b5d727Sbeck 	failures += runcompare(test_drounveil);
9250d000527Sbeck 	failures += runcompare(test_r);
9260d000527Sbeck 	failures += runcompare(test_rw);
9270d000527Sbeck 	failures += runcompare(test_x);
9280d000527Sbeck 	failures += runcompare(test_unlink);
9290d000527Sbeck 	failures += runcompare(test_link);
9300d000527Sbeck 	failures += runcompare(test_chdir);
9310d000527Sbeck 	failures += runcompare(test_rename);
9320d000527Sbeck 	failures += runcompare(test_access);
9330d000527Sbeck 	failures += runcompare(test_chflags);
9340d000527Sbeck 	failures += runcompare(test_stat);
935ba253c9bSbeck 	failures += runcompare(test_stat2);
9360d000527Sbeck 	failures += runcompare(test_statfs);
9370d000527Sbeck 	failures += runcompare(test_symlink);
9380d000527Sbeck 	failures += runcompare(test_chmod);
9390d000527Sbeck 	failures += runcompare(test_exec);
9400d000527Sbeck 	failures += runcompare(test_exec2);
9414772489dSbeck 	failures += runcompare(test_realpath);
9429cf24395Sbeck 	failures += runcompare(test_parent_dir);
94319e2994eSbeck 	failures += runcompare(test_slash);
944ff8da2f7Sbeck 	failures += runcompare(test_dot);
9459a5a31c7Srobert 	failures += runcompare(test_bypassunveil);
94613e6c35fSbeck 	failures += runcompare_internal(test_fork, 0);
9473765a54cSbeck 	failures += runcompare(test_dotdotup);
9486fd26cb2Sbeck 	failures += runcompare(test_kn);
94905b775d5Sbeck 	failures += runcompare(test_pathdiscover);
9502f30fa3dSclaudio 	failures += runcompare(test_fchdir);
951d903b886Sclaudio 	failures += runcompare(test_fork_locked);
952748ad6d0Sclaudio 	failures += runcompare(test_intermediate_node);
953748ad6d0Sclaudio 	failures += runcompare(test_noaccess_node);
9540d000527Sbeck 	exit(failures);
9550d000527Sbeck }
956