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