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