]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/capsicum-test/socket.cc
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / contrib / capsicum-test / socket.cc
1 // Tests for socket functionality.
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <sys/un.h>
5 #include <netinet/in.h>
6 #include <arpa/inet.h>
7 #include <unistd.h>
8
9 #include <string>
10
11 #include "capsicum.h"
12 #include "syscalls.h"
13 #include "capsicum-test.h"
14
15 TEST(Socket, UnixDomain) {
16   const char* socketName = TmpFile("capsicum-test.socket");
17   unlink(socketName);
18   cap_rights_t r_rw;
19   cap_rights_init(&r_rw, CAP_READ, CAP_WRITE);
20   cap_rights_t r_all;
21   cap_rights_init(&r_all, CAP_READ, CAP_WRITE, CAP_SOCK_CLIENT, CAP_SOCK_SERVER);
22
23   pid_t child = fork();
24   if (child == 0) {
25     // Child process: wait for server setup
26     sleep(1);
27
28     // Create sockets
29     int sock = socket(AF_UNIX, SOCK_STREAM, 0);
30     EXPECT_OK(sock);
31     if (sock < 0) return;
32
33     int cap_sock_rw = dup(sock);
34     EXPECT_OK(cap_sock_rw);
35     EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
36     int cap_sock_all = dup(sock);
37     EXPECT_OK(cap_sock_all);
38     EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
39     EXPECT_OK(close(sock));
40
41     // Connect socket
42     struct sockaddr_un un;
43     memset(&un, 0, sizeof(un));
44     un.sun_family = AF_UNIX;
45     strcpy(un.sun_path, socketName);
46     socklen_t len = sizeof(un);
47     EXPECT_NOTCAPABLE(connect_(cap_sock_rw, (struct sockaddr *)&un, len));
48     EXPECT_OK(connect_(cap_sock_all, (struct sockaddr *)&un, len));
49
50     exit(HasFailure());
51   }
52
53   int sock = socket(AF_UNIX, SOCK_STREAM, 0);
54   EXPECT_OK(sock);
55   if (sock < 0) return;
56
57   int cap_sock_rw = dup(sock);
58   EXPECT_OK(cap_sock_rw);
59   EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
60   int cap_sock_all = dup(sock);
61   EXPECT_OK(cap_sock_all);
62   EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
63   EXPECT_OK(close(sock));
64
65   struct sockaddr_un un;
66   memset(&un, 0, sizeof(un));
67   un.sun_family = AF_UNIX;
68   strcpy(un.sun_path, socketName);
69   socklen_t len =  (sizeof(un) - sizeof(un.sun_path) + strlen(un.sun_path));
70
71   // Can only bind the fully-capable socket.
72   EXPECT_NOTCAPABLE(bind_(cap_sock_rw, (struct sockaddr *)&un, len));
73   EXPECT_OK(bind_(cap_sock_all, (struct sockaddr *)&un, len));
74
75   // Can only listen on the fully-capable socket.
76   EXPECT_NOTCAPABLE(listen(cap_sock_rw, 3));
77   EXPECT_OK(listen(cap_sock_all, 3));
78
79   // Can only do socket operations on the fully-capable socket.
80   len = sizeof(un);
81   EXPECT_NOTCAPABLE(getsockname(cap_sock_rw, (struct sockaddr*)&un, &len));
82   int value = 0;
83   EXPECT_NOTCAPABLE(setsockopt(cap_sock_rw, SOL_SOCKET, SO_DEBUG, &value, sizeof(value)));
84   len = sizeof(value);
85   EXPECT_NOTCAPABLE(getsockopt(cap_sock_rw, SOL_SOCKET, SO_DEBUG, &value, &len));
86
87   len = sizeof(un);
88   memset(&un, 0, sizeof(un));
89   EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr*)&un, &len));
90   EXPECT_EQ(AF_UNIX, un.sun_family);
91   EXPECT_EQ(std::string(socketName), std::string(un.sun_path));
92   value = 0;
93   EXPECT_OK(setsockopt(cap_sock_all, SOL_SOCKET, SO_DEBUG, &value, sizeof(value)));
94   len = sizeof(value);
95   EXPECT_OK(getsockopt(cap_sock_all, SOL_SOCKET, SO_DEBUG, &value, &len));
96
97   // Accept the incoming connection
98   len = sizeof(un);
99   memset(&un, 0, sizeof(un));
100   EXPECT_NOTCAPABLE(accept(cap_sock_rw, (struct sockaddr *)&un, &len));
101   int conn_fd = accept(cap_sock_all, (struct sockaddr *)&un, &len);
102   EXPECT_OK(conn_fd);
103
104 #ifdef CAP_FROM_ACCEPT
105   // New connection should also be a capability.
106   cap_rights_t rights;
107   cap_rights_init(&rights, 0);
108   EXPECT_OK(cap_rights_get(conn_fd, &rights));
109   EXPECT_RIGHTS_IN(&rights, &r_all);
110 #endif
111
112   // Wait for the child.
113   int status;
114   EXPECT_EQ(child, waitpid(child, &status, 0));
115   int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
116   EXPECT_EQ(0, rc);
117
118   close(conn_fd);
119   close(cap_sock_rw);
120   close(cap_sock_all);
121   unlink(socketName);
122 }
123
124 TEST(Socket, TCP) {
125   int sock = socket(AF_INET, SOCK_STREAM, 0);
126   EXPECT_OK(sock);
127   if (sock < 0) return;
128
129   cap_rights_t r_rw;
130   cap_rights_init(&r_rw, CAP_READ, CAP_WRITE);
131   cap_rights_t r_all;
132   cap_rights_init(&r_all, CAP_READ, CAP_WRITE, CAP_SOCK_CLIENT, CAP_SOCK_SERVER);
133
134   int cap_sock_rw = dup(sock);
135   EXPECT_OK(cap_sock_rw);
136   EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
137   int cap_sock_all = dup(sock);
138   EXPECT_OK(cap_sock_all);
139   EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
140   close(sock);
141
142   struct sockaddr_in addr;
143   memset(&addr, 0, sizeof(addr));
144   addr.sin_family = AF_INET;
145   addr.sin_port = htons(0);
146   addr.sin_addr.s_addr = htonl(INADDR_ANY);
147   socklen_t len = sizeof(addr);
148
149   // Can only bind the fully-capable socket.
150   EXPECT_NOTCAPABLE(bind_(cap_sock_rw, (struct sockaddr *)&addr, len));
151   EXPECT_OK(bind_(cap_sock_all, (struct sockaddr *)&addr, len));
152
153   getsockname(cap_sock_all, (struct sockaddr *)&addr, &len);
154   int port = ntohs(addr.sin_port);
155
156   // Now we know the port involved, fork off a child.
157   pid_t child = fork();
158   if (child == 0) {
159     // Child process: wait for server setup
160     sleep(1);
161
162     // Create sockets
163     int sock = socket(AF_INET, SOCK_STREAM, 0);
164     EXPECT_OK(sock);
165     if (sock < 0) return;
166     int cap_sock_rw = dup(sock);
167     EXPECT_OK(cap_sock_rw);
168     EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
169     int cap_sock_all = dup(sock);
170     EXPECT_OK(cap_sock_all);
171     EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
172     close(sock);
173
174     // Connect socket
175     struct sockaddr_in addr;
176     memset(&addr, 0, sizeof(addr));
177     addr.sin_family = AF_INET;
178     addr.sin_port = htons(port);  // Pick unused port
179     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
180     socklen_t len = sizeof(addr);
181     EXPECT_NOTCAPABLE(connect_(cap_sock_rw, (struct sockaddr *)&addr, len));
182     EXPECT_OK(connect_(cap_sock_all, (struct sockaddr *)&addr, len));
183
184     exit(HasFailure());
185   }
186
187   // Can only listen on the fully-capable socket.
188   EXPECT_NOTCAPABLE(listen(cap_sock_rw, 3));
189   EXPECT_OK(listen(cap_sock_all, 3));
190
191   // Can only do socket operations on the fully-capable socket.
192   len = sizeof(addr);
193   EXPECT_NOTCAPABLE(getsockname(cap_sock_rw, (struct sockaddr*)&addr, &len));
194   int value = 1;
195   EXPECT_NOTCAPABLE(setsockopt(cap_sock_rw, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)));
196   len = sizeof(value);
197   EXPECT_NOTCAPABLE(getsockopt(cap_sock_rw, SOL_SOCKET, SO_REUSEPORT, &value, &len));
198
199   len = sizeof(addr);
200   memset(&addr, 0, sizeof(addr));
201   EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr*)&addr, &len));
202   EXPECT_EQ(AF_INET, addr.sin_family);
203   EXPECT_EQ(htons(port), addr.sin_port);
204   value = 0;
205   EXPECT_OK(setsockopt(cap_sock_all, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)));
206   len = sizeof(value);
207   EXPECT_OK(getsockopt(cap_sock_all, SOL_SOCKET, SO_REUSEPORT, &value, &len));
208
209   // Accept the incoming connection
210   len = sizeof(addr);
211   memset(&addr, 0, sizeof(addr));
212   EXPECT_NOTCAPABLE(accept(cap_sock_rw, (struct sockaddr *)&addr, &len));
213   int conn_fd = accept(cap_sock_all, (struct sockaddr *)&addr, &len);
214   EXPECT_OK(conn_fd);
215
216 #ifdef CAP_FROM_ACCEPT
217   // New connection should also be a capability.
218   cap_rights_t rights;
219   cap_rights_init(&rights, 0);
220   EXPECT_OK(cap_rights_get(conn_fd, &rights));
221   EXPECT_RIGHTS_IN(&rights, &r_all);
222 #endif
223
224   // Wait for the child.
225   int status;
226   EXPECT_EQ(child, waitpid(child, &status, 0));
227   int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
228   EXPECT_EQ(0, rc);
229
230   close(conn_fd);
231   close(cap_sock_rw);
232   close(cap_sock_all);
233 }
234
235 TEST(Socket, UDP) {
236   int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
237   EXPECT_OK(sock);
238   if (sock < 0) return;
239
240   cap_rights_t r_rw;
241   cap_rights_init(&r_rw, CAP_READ, CAP_WRITE);
242   cap_rights_t r_all;
243   cap_rights_init(&r_all, CAP_READ, CAP_WRITE, CAP_SOCK_CLIENT, CAP_SOCK_SERVER);
244   cap_rights_t r_connect;
245   cap_rights_init(&r_connect, CAP_READ, CAP_WRITE, CAP_CONNECT);
246
247   int cap_sock_rw = dup(sock);
248   EXPECT_OK(cap_sock_rw);
249   EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
250   int cap_sock_all = dup(sock);
251   EXPECT_OK(cap_sock_all);
252   EXPECT_OK(cap_rights_limit(cap_sock_all, &r_all));
253   close(sock);
254
255   struct sockaddr_in addr;
256   memset(&addr, 0, sizeof(addr));
257   addr.sin_family = AF_INET;
258   addr.sin_port = htons(0);
259   addr.sin_addr.s_addr = htonl(INADDR_ANY);
260   socklen_t len = sizeof(addr);
261
262   // Can only bind the fully-capable socket.
263   EXPECT_NOTCAPABLE(bind_(cap_sock_rw, (struct sockaddr *)&addr, len));
264   EXPECT_OK(bind_(cap_sock_all, (struct sockaddr *)&addr, len));
265   getsockname(cap_sock_all, (struct sockaddr *)&addr, &len);
266   int port = ntohs(addr.sin_port);
267
268   // Can only do socket operations on the fully-capable socket.
269   len = sizeof(addr);
270   EXPECT_NOTCAPABLE(getsockname(cap_sock_rw, (struct sockaddr*)&addr, &len));
271   int value = 1;
272   EXPECT_NOTCAPABLE(setsockopt(cap_sock_rw, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)));
273   len = sizeof(value);
274   EXPECT_NOTCAPABLE(getsockopt(cap_sock_rw, SOL_SOCKET, SO_REUSEPORT, &value, &len));
275
276   len = sizeof(addr);
277   memset(&addr, 0, sizeof(addr));
278   EXPECT_OK(getsockname(cap_sock_all, (struct sockaddr*)&addr, &len));
279   EXPECT_EQ(AF_INET, addr.sin_family);
280   EXPECT_EQ(htons(port), addr.sin_port);
281   value = 1;
282   EXPECT_OK(setsockopt(cap_sock_all, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)));
283   len = sizeof(value);
284   EXPECT_OK(getsockopt(cap_sock_all, SOL_SOCKET, SO_REUSEPORT, &value, &len));
285
286   pid_t child = fork();
287   if (child == 0) {
288     int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
289     EXPECT_OK(sock);
290     int cap_sock_rw = dup(sock);
291     EXPECT_OK(cap_sock_rw);
292     EXPECT_OK(cap_rights_limit(cap_sock_rw, &r_rw));
293     int cap_sock_connect = dup(sock);
294     EXPECT_OK(cap_sock_connect);
295     EXPECT_OK(cap_rights_limit(cap_sock_connect, &r_connect));
296     close(sock);
297
298     // Can only sendmsg(2) to an address over a socket with CAP_CONNECT.
299     unsigned char buffer[256];
300     struct iovec iov;
301     memset(&iov, 0, sizeof(iov));
302     iov.iov_base = buffer;
303     iov.iov_len = sizeof(buffer);
304
305     struct msghdr mh;
306     memset(&mh, 0, sizeof(mh));
307     mh.msg_iov = &iov;
308     mh.msg_iovlen = 1;
309
310     struct sockaddr_in addr;
311     memset(&addr, 0, sizeof(addr));
312     addr.sin_family = AF_INET;
313     addr.sin_port = htons(port);
314     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
315     mh.msg_name = &addr;
316     mh.msg_namelen = sizeof(addr);
317
318     EXPECT_NOTCAPABLE(sendmsg(cap_sock_rw, &mh, 0));
319     EXPECT_OK(sendmsg(cap_sock_connect, &mh, 0));
320
321 #ifdef HAVE_SEND_RECV_MMSG
322     struct mmsghdr mv;
323     memset(&mv, 0, sizeof(mv));
324     memcpy(&mv.msg_hdr, &mh, sizeof(struct msghdr));
325     EXPECT_NOTCAPABLE(sendmmsg(cap_sock_rw, &mv, 1, 0));
326     EXPECT_OK(sendmmsg(cap_sock_connect, &mv, 1, 0));
327 #endif
328     close(cap_sock_rw);
329     close(cap_sock_connect);
330     exit(HasFailure());
331   }
332   // Wait for the child.
333   int status;
334   EXPECT_EQ(child, waitpid(child, &status, 0));
335   int rc = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
336   EXPECT_EQ(0, rc);
337
338   close(cap_sock_rw);
339   close(cap_sock_all);
340 }