1 #include <sys/types.h>
2 #include <sys/jail.h>
3 #include <sys/wait.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 void setup();
9 void teardown();
10
11 uid_t unpriv_uid = 5000;
12 gid_t unpriv_gid = 5000;
13
14 void
test(int (* fn)(),int expected,char * msg,char * msg2)15 test(int (*fn)(), int expected, char *msg, char *msg2)
16 {
17 int retval;
18
19 setup();
20 retval = fn();
21 teardown();
22
23 printf("%s (%s): ", msg, msg2);
24
25 if (retval == expected) {
26 printf("OK\n");
27 } else {
28 printf("FAILED (was: %d, expected: %d)\n", retval, expected);
29 }
30 fflush(stdout);
31 }
32
33 void
test_as_root(int (* fn)(),int expected,char * msg)34 test_as_root(int (*fn)(), int expected, char *msg)
35 {
36 if (getuid() != 0) {
37 fprintf(stderr, "must be run as root\n");
38 exit(-1);
39 }
40
41 test(fn, expected, msg, "as root");
42 }
43
44 void
test_as_jailed_root(int (* fn)(),int expected,char * msg)45 test_as_jailed_root(int (*fn)(), int expected, char *msg)
46 {
47 if (getuid() != 0) {
48 fprintf(stderr, "must be run as root\n");
49 exit(-1);
50 }
51
52 int child = fork();
53
54 if (child == -1) {
55 fprintf(stderr, "fork failed\n");
56 exit(-2);
57 }
58
59 if (child) {
60 struct jail j;
61 j.version = 1;
62 j.path = "/";
63 j.hostname = "jail";
64 j.n_ips = 0;
65
66 int jid = jail(&j);
67 if (jid < 0) {
68 fprintf(stderr, "jail failed\n");
69 exit(-1); // TODO
70 }
71 test(fn, expected, msg, "as jailed root");
72 exit(0);
73 }
74 else {
75 waitpid(child, NULL, 0);
76 }
77 }
78
79 void
test_as_unpriv(int (* fn)(),int expected,char * msg)80 test_as_unpriv(int (*fn)(), int expected, char *msg)
81 {
82 if (getuid() != 0) {
83 fprintf(stderr, "must be run as root\n");
84 exit(-1);
85 }
86
87 int child = fork();
88
89 if (child == -1) {
90 fprintf(stderr, "fork failed\n");
91 exit(-2);
92 }
93
94 if (child) {
95 setgid(unpriv_gid);
96 setuid(unpriv_uid);
97
98 if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
99 fprintf(stderr, "setuid/gid failed\n");
100 exit(-1); // TODO
101 }
102 test(fn, expected, msg, "as unpriv");
103 exit(0);
104 }
105 else {
106 waitpid(child, NULL, 0);
107 }
108 }
109
110 void
test_as_jailed_unpriv(int (* fn)(),int expected,char * msg)111 test_as_jailed_unpriv(int (*fn)(), int expected, char *msg)
112 {
113 if (getuid() != 0) {
114 fprintf(stderr, "must be run as root\n");
115 exit(-1);
116 }
117
118 int child = fork();
119
120 if (child == -1) {
121 fprintf(stderr, "fork failed\n");
122 exit(-2);
123 }
124
125 if (child) {
126 struct jail j;
127 j.version = 1;
128 j.path = "/";
129 j.hostname = "jail";
130 j.n_ips = 0;
131
132 int jid = jail(&j);
133 if (jid < 0) {
134 fprintf(stderr, "jail failed\n");
135 exit(-1); // TODO
136 }
137
138 setgid(unpriv_gid);
139 setuid(unpriv_uid);
140
141 if (getuid() != unpriv_uid || getgid() != unpriv_gid) {
142 fprintf(stderr, "setuid/gid failed\n");
143 exit(-1); // TODO
144 }
145 test(fn, expected, msg, "as jailed unpriv");
146 exit(0);
147 }
148 else {
149 waitpid(child, NULL, 0);
150 }
151 }
152