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