xref: /openbsd/regress/sys/kern/unveil/unveil.h (revision b749d6b5)
1 #include <sys/stat.h>
2 #include <sys/wait.h>
3 
4 #include <err.h>
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 
9 #define UV_SHOULD_SUCCEED(A, B) do {					\
10 	if (A) {							\
11 		err(1, "%s:%d - %s", __FILE__, __LINE__, B);		\
12 	}								\
13 } while (0)
14 
15 #define UV_SHOULD_ENOENT(A, B) do {					\
16 	if (A) {							\
17 		if (do_uv && errno != ENOENT)				\
18 			err(1, "%s:%d - %s", __FILE__, __LINE__, B);	\
19 	} else {							\
20 		if (do_uv)						\
21 			errx(1, "%s:%d - %s worked when it should not "	\
22 			    "have",  __FILE__, __LINE__, B);		\
23 	}								\
24 } while(0)
25 
26 #define UV_SHOULD_EACCES(A, B) do {					\
27 	if (A) {							\
28 		if (do_uv && errno != EACCES)				\
29 			err(1, "%s:%d - %s", __FILE__, __LINE__, B);	\
30 	} else {							\
31 		if (do_uv)						\
32 			errx(1, "%s:%d - %s worked when it should not "	\
33 			    "have",  __FILE__, __LINE__, B);		\
34 	}								\
35 } while(0)
36 
37 #define UV_SHOULD_EPERM(A, B) do {					\
38 	if (A) {							\
39 		if (do_uv && errno != EPERM)				\
40 			err(1, "%s:%d - %s", __FILE__, __LINE__, B);	\
41 	} else {							\
42 		if (do_uv)						\
43 			errx(1, "%s:%d - %s worked when it should not "	\
44 			    "have",  __FILE__, __LINE__, B);		\
45 	}								\
46 } while(0)
47 
48 static char uv_dir1[] = "/tmp/uvdir1.XXXXXX"; /* unveiled */
49 static char uv_dir2[] = "/tmp/uvdir2.XXXXXX"; /* not unveiled */
50 static char uv_file1[] = "/tmp/uvfile1.XXXXXX"; /* unveiled */
51 static char uv_file2[] = "/tmp/uvfile2.XXXXXX"; /* not unveiled */
52 
53 static int
runcompare_internal(int (* func)(int),int fail_ok)54 runcompare_internal(int (*func)(int), int fail_ok)
55 {
56 	int unveil = 0, nonunveil = 0;
57 	int status;
58 	pid_t pid = fork();
59 	if (pid == 0)
60 		exit(func(0));
61 	status = 0;
62 	waitpid(pid, &status, 0);
63 	if (WIFEXITED(status))
64 		nonunveil = WEXITSTATUS(status);
65 	if (WIFSIGNALED(status)) {
66 		printf("[FAIL] nonunveil exited with signal %d\n",
67 		    WTERMSIG(status));
68 		goto fail;
69 	}
70 	pid = fork();
71 	if (pid == 0)
72 		exit(func(1));
73 	status = 0;
74 	waitpid(pid, &status, 0);
75 	if (WIFEXITED(status))
76 		unveil = WEXITSTATUS(status);
77 	if (WIFSIGNALED(status)) {
78 		printf("[FAIL] nonunveil exited with signal %d\n",
79 		    WTERMSIG(status));
80 		goto fail;
81 	}
82 	if (!fail_ok && (unveil || nonunveil)) {
83 		printf("[FAIL] unveil = %d, nonunveil = %d\n", unveil,
84 		    nonunveil);
85 		goto fail;
86 	}
87 	if (unveil == nonunveil)
88 		return 0;
89 	printf("[FAIL] unveil = %d, nonunveil = %d\n", unveil, nonunveil);
90  fail:
91 	return 1;
92 }
93 
94 static int
runcompare(int (* func)(int))95 runcompare(int (*func)(int))
96 {
97 	return runcompare_internal(func, 1);
98 }
99 
100 static void
test_setup(void)101 test_setup(void)
102 {
103 	int fd1, fd2;
104 	char filename[256];
105 
106 	UV_SHOULD_SUCCEED((mkdtemp(uv_dir1) == NULL), "mkdtmp");
107 	UV_SHOULD_SUCCEED((mkdtemp(uv_dir2) == NULL), "mkdtmp");
108 	UV_SHOULD_SUCCEED(((fd1 = mkstemp(uv_file1)) == -1), "mkstemp");
109 	close(fd1);
110 	UV_SHOULD_SUCCEED((chmod(uv_file1, S_IRWXU) == -1), "chmod");
111 	UV_SHOULD_SUCCEED(((fd2 = mkstemp(uv_file2)) == -1), "mkstemp");
112 	(void)snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir1);
113 	UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
114 	(void)snprintf(filename, sizeof(filename), "/%s/subdir", uv_dir2);
115 	UV_SHOULD_SUCCEED((mkdir(filename, 0777) == -1), "mkdir");
116 	close(fd2);
117 }
118