1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * vsock_test - vsock.ko test suite
4 *
5 * Copyright (C) 2017 Red Hat, Inc.
6 *
7 * Author: Stefan Hajnoczi <stefanha@redhat.com>
8 */
9
10 #include <getopt.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <linux/kernel.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <time.h>
20 #include <sys/mman.h>
21 #include <poll.h>
22 #include <signal.h>
23 #include <sys/ioctl.h>
24 #include <linux/time64.h>
25
26 #include "vsock_test_zerocopy.h"
27 #include "timeout.h"
28 #include "control.h"
29 #include "util.h"
30
31 /* Basic messages for control_writeulong(), control_readulong() */
32 #define CONTROL_CONTINUE 1
33 #define CONTROL_DONE 0
34
test_stream_connection_reset(const struct test_opts * opts)35 static void test_stream_connection_reset(const struct test_opts *opts)
36 {
37 union {
38 struct sockaddr sa;
39 struct sockaddr_vm svm;
40 } addr = {
41 .svm = {
42 .svm_family = AF_VSOCK,
43 .svm_port = opts->peer_port,
44 .svm_cid = opts->peer_cid,
45 },
46 };
47 int ret;
48 int fd;
49
50 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
51
52 timeout_begin(TIMEOUT);
53 do {
54 ret = connect(fd, &addr.sa, sizeof(addr.svm));
55 timeout_check("connect");
56 } while (ret < 0 && errno == EINTR);
57 timeout_end();
58
59 if (ret != -1) {
60 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
61 exit(EXIT_FAILURE);
62 }
63 if (errno != ECONNRESET) {
64 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
65 exit(EXIT_FAILURE);
66 }
67
68 close(fd);
69 }
70
test_stream_bind_only_client(const struct test_opts * opts)71 static void test_stream_bind_only_client(const struct test_opts *opts)
72 {
73 union {
74 struct sockaddr sa;
75 struct sockaddr_vm svm;
76 } addr = {
77 .svm = {
78 .svm_family = AF_VSOCK,
79 .svm_port = opts->peer_port,
80 .svm_cid = opts->peer_cid,
81 },
82 };
83 int ret;
84 int fd;
85
86 /* Wait for the server to be ready */
87 control_expectln("BIND");
88
89 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
90
91 timeout_begin(TIMEOUT);
92 do {
93 ret = connect(fd, &addr.sa, sizeof(addr.svm));
94 timeout_check("connect");
95 } while (ret < 0 && errno == EINTR);
96 timeout_end();
97
98 if (ret != -1) {
99 fprintf(stderr, "expected connect(2) failure, got %d\n", ret);
100 exit(EXIT_FAILURE);
101 }
102 if (errno != ECONNRESET) {
103 fprintf(stderr, "unexpected connect(2) errno %d\n", errno);
104 exit(EXIT_FAILURE);
105 }
106
107 /* Notify the server that the client has finished */
108 control_writeln("DONE");
109
110 close(fd);
111 }
112
test_stream_bind_only_server(const struct test_opts * opts)113 static void test_stream_bind_only_server(const struct test_opts *opts)
114 {
115 int fd;
116
117 fd = vsock_bind(VMADDR_CID_ANY, opts->peer_port, SOCK_STREAM);
118
119 /* Notify the client that the server is ready */
120 control_writeln("BIND");
121
122 /* Wait for the client to finish */
123 control_expectln("DONE");
124
125 close(fd);
126 }
127
test_stream_client_close_client(const struct test_opts * opts)128 static void test_stream_client_close_client(const struct test_opts *opts)
129 {
130 int fd;
131
132 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
133 if (fd < 0) {
134 perror("connect");
135 exit(EXIT_FAILURE);
136 }
137
138 send_byte(fd, 1, 0);
139 close(fd);
140 }
141
test_stream_client_close_server(const struct test_opts * opts)142 static void test_stream_client_close_server(const struct test_opts *opts)
143 {
144 int fd;
145
146 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
147 if (fd < 0) {
148 perror("accept");
149 exit(EXIT_FAILURE);
150 }
151
152 /* Wait for the remote to close the connection, before check
153 * -EPIPE error on send.
154 */
155 vsock_wait_remote_close(fd);
156
157 send_byte(fd, -EPIPE, 0);
158 recv_byte(fd, 1, 0);
159 recv_byte(fd, 0, 0);
160 close(fd);
161 }
162
test_stream_server_close_client(const struct test_opts * opts)163 static void test_stream_server_close_client(const struct test_opts *opts)
164 {
165 int fd;
166
167 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
168 if (fd < 0) {
169 perror("connect");
170 exit(EXIT_FAILURE);
171 }
172
173 /* Wait for the remote to close the connection, before check
174 * -EPIPE error on send.
175 */
176 vsock_wait_remote_close(fd);
177
178 send_byte(fd, -EPIPE, 0);
179 recv_byte(fd, 1, 0);
180 recv_byte(fd, 0, 0);
181 close(fd);
182 }
183
test_stream_server_close_server(const struct test_opts * opts)184 static void test_stream_server_close_server(const struct test_opts *opts)
185 {
186 int fd;
187
188 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
189 if (fd < 0) {
190 perror("accept");
191 exit(EXIT_FAILURE);
192 }
193
194 send_byte(fd, 1, 0);
195 close(fd);
196 }
197
198 /* With the standard socket sizes, VMCI is able to support about 100
199 * concurrent stream connections.
200 */
201 #define MULTICONN_NFDS 100
202
test_stream_multiconn_client(const struct test_opts * opts)203 static void test_stream_multiconn_client(const struct test_opts *opts)
204 {
205 int fds[MULTICONN_NFDS];
206 int i;
207
208 for (i = 0; i < MULTICONN_NFDS; i++) {
209 fds[i] = vsock_stream_connect(opts->peer_cid, opts->peer_port);
210 if (fds[i] < 0) {
211 perror("connect");
212 exit(EXIT_FAILURE);
213 }
214 }
215
216 for (i = 0; i < MULTICONN_NFDS; i++) {
217 if (i % 2)
218 recv_byte(fds[i], 1, 0);
219 else
220 send_byte(fds[i], 1, 0);
221 }
222
223 for (i = 0; i < MULTICONN_NFDS; i++)
224 close(fds[i]);
225 }
226
test_stream_multiconn_server(const struct test_opts * opts)227 static void test_stream_multiconn_server(const struct test_opts *opts)
228 {
229 int fds[MULTICONN_NFDS];
230 int i;
231
232 for (i = 0; i < MULTICONN_NFDS; i++) {
233 fds[i] = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
234 if (fds[i] < 0) {
235 perror("accept");
236 exit(EXIT_FAILURE);
237 }
238 }
239
240 for (i = 0; i < MULTICONN_NFDS; i++) {
241 if (i % 2)
242 send_byte(fds[i], 1, 0);
243 else
244 recv_byte(fds[i], 1, 0);
245 }
246
247 for (i = 0; i < MULTICONN_NFDS; i++)
248 close(fds[i]);
249 }
250
251 #define MSG_PEEK_BUF_LEN 64
252
test_msg_peek_client(const struct test_opts * opts,bool seqpacket)253 static void test_msg_peek_client(const struct test_opts *opts,
254 bool seqpacket)
255 {
256 unsigned char buf[MSG_PEEK_BUF_LEN];
257 int fd;
258 int i;
259
260 if (seqpacket)
261 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
262 else
263 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
264
265 if (fd < 0) {
266 perror("connect");
267 exit(EXIT_FAILURE);
268 }
269
270 for (i = 0; i < sizeof(buf); i++)
271 buf[i] = rand() & 0xFF;
272
273 control_expectln("SRVREADY");
274
275 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
276
277 close(fd);
278 }
279
test_msg_peek_server(const struct test_opts * opts,bool seqpacket)280 static void test_msg_peek_server(const struct test_opts *opts,
281 bool seqpacket)
282 {
283 unsigned char buf_half[MSG_PEEK_BUF_LEN / 2];
284 unsigned char buf_normal[MSG_PEEK_BUF_LEN];
285 unsigned char buf_peek[MSG_PEEK_BUF_LEN];
286 int fd;
287
288 if (seqpacket)
289 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
290 else
291 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
292
293 if (fd < 0) {
294 perror("accept");
295 exit(EXIT_FAILURE);
296 }
297
298 /* Peek from empty socket. */
299 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK | MSG_DONTWAIT,
300 -EAGAIN);
301
302 control_writeln("SRVREADY");
303
304 /* Peek part of data. */
305 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK, sizeof(buf_half));
306
307 /* Peek whole data. */
308 recv_buf(fd, buf_peek, sizeof(buf_peek), MSG_PEEK, sizeof(buf_peek));
309
310 /* Compare partial and full peek. */
311 if (memcmp(buf_half, buf_peek, sizeof(buf_half))) {
312 fprintf(stderr, "Partial peek data mismatch\n");
313 exit(EXIT_FAILURE);
314 }
315
316 if (seqpacket) {
317 /* This type of socket supports MSG_TRUNC flag,
318 * so check it with MSG_PEEK. We must get length
319 * of the message.
320 */
321 recv_buf(fd, buf_half, sizeof(buf_half), MSG_PEEK | MSG_TRUNC,
322 sizeof(buf_peek));
323 }
324
325 recv_buf(fd, buf_normal, sizeof(buf_normal), 0, sizeof(buf_normal));
326
327 /* Compare full peek and normal read. */
328 if (memcmp(buf_peek, buf_normal, sizeof(buf_peek))) {
329 fprintf(stderr, "Full peek data mismatch\n");
330 exit(EXIT_FAILURE);
331 }
332
333 close(fd);
334 }
335
test_stream_msg_peek_client(const struct test_opts * opts)336 static void test_stream_msg_peek_client(const struct test_opts *opts)
337 {
338 return test_msg_peek_client(opts, false);
339 }
340
test_stream_msg_peek_server(const struct test_opts * opts)341 static void test_stream_msg_peek_server(const struct test_opts *opts)
342 {
343 return test_msg_peek_server(opts, false);
344 }
345
346 #define SOCK_BUF_SIZE (2 * 1024 * 1024)
347 #define MAX_MSG_PAGES 4
348
test_seqpacket_msg_bounds_client(const struct test_opts * opts)349 static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
350 {
351 unsigned long curr_hash;
352 size_t max_msg_size;
353 int page_size;
354 int msg_count;
355 int fd;
356
357 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
358 if (fd < 0) {
359 perror("connect");
360 exit(EXIT_FAILURE);
361 }
362
363 /* Wait, until receiver sets buffer size. */
364 control_expectln("SRVREADY");
365
366 curr_hash = 0;
367 page_size = getpagesize();
368 max_msg_size = MAX_MSG_PAGES * page_size;
369 msg_count = SOCK_BUF_SIZE / max_msg_size;
370
371 for (int i = 0; i < msg_count; i++) {
372 size_t buf_size;
373 int flags;
374 void *buf;
375
376 /* Use "small" buffers and "big" buffers. */
377 if (i & 1)
378 buf_size = page_size +
379 (rand() % (max_msg_size - page_size));
380 else
381 buf_size = 1 + (rand() % page_size);
382
383 buf = malloc(buf_size);
384
385 if (!buf) {
386 perror("malloc");
387 exit(EXIT_FAILURE);
388 }
389
390 memset(buf, rand() & 0xff, buf_size);
391 /* Set at least one MSG_EOR + some random. */
392 if (i == (msg_count / 2) || (rand() & 1)) {
393 flags = MSG_EOR;
394 curr_hash++;
395 } else {
396 flags = 0;
397 }
398
399 send_buf(fd, buf, buf_size, flags, buf_size);
400
401 /*
402 * Hash sum is computed at both client and server in
403 * the same way:
404 * H += hash('message data')
405 * Such hash "controls" both data integrity and message
406 * bounds. After data exchange, both sums are compared
407 * using control socket, and if message bounds wasn't
408 * broken - two values must be equal.
409 */
410 curr_hash += hash_djb2(buf, buf_size);
411 free(buf);
412 }
413
414 control_writeln("SENDDONE");
415 control_writeulong(curr_hash);
416 close(fd);
417 }
418
test_seqpacket_msg_bounds_server(const struct test_opts * opts)419 static void test_seqpacket_msg_bounds_server(const struct test_opts *opts)
420 {
421 unsigned long long sock_buf_size;
422 unsigned long remote_hash;
423 unsigned long curr_hash;
424 int fd;
425 struct msghdr msg = {0};
426 struct iovec iov = {0};
427
428 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
429 if (fd < 0) {
430 perror("accept");
431 exit(EXIT_FAILURE);
432 }
433
434 sock_buf_size = SOCK_BUF_SIZE;
435
436 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
437 sock_buf_size,
438 "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
439
440 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
441 sock_buf_size,
442 "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
443
444 /* Ready to receive data. */
445 control_writeln("SRVREADY");
446 /* Wait, until peer sends whole data. */
447 control_expectln("SENDDONE");
448 iov.iov_len = MAX_MSG_PAGES * getpagesize();
449 iov.iov_base = malloc(iov.iov_len);
450 if (!iov.iov_base) {
451 perror("malloc");
452 exit(EXIT_FAILURE);
453 }
454
455 msg.msg_iov = &iov;
456 msg.msg_iovlen = 1;
457
458 curr_hash = 0;
459
460 while (1) {
461 ssize_t recv_size;
462
463 recv_size = recvmsg(fd, &msg, 0);
464
465 if (!recv_size)
466 break;
467
468 if (recv_size < 0) {
469 perror("recvmsg");
470 exit(EXIT_FAILURE);
471 }
472
473 if (msg.msg_flags & MSG_EOR)
474 curr_hash++;
475
476 curr_hash += hash_djb2(msg.msg_iov[0].iov_base, recv_size);
477 }
478
479 free(iov.iov_base);
480 close(fd);
481 remote_hash = control_readulong();
482
483 if (curr_hash != remote_hash) {
484 fprintf(stderr, "Message bounds broken\n");
485 exit(EXIT_FAILURE);
486 }
487 }
488
489 #define MESSAGE_TRUNC_SZ 32
test_seqpacket_msg_trunc_client(const struct test_opts * opts)490 static void test_seqpacket_msg_trunc_client(const struct test_opts *opts)
491 {
492 int fd;
493 char buf[MESSAGE_TRUNC_SZ];
494
495 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
496 if (fd < 0) {
497 perror("connect");
498 exit(EXIT_FAILURE);
499 }
500
501 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
502
503 control_writeln("SENDDONE");
504 close(fd);
505 }
506
test_seqpacket_msg_trunc_server(const struct test_opts * opts)507 static void test_seqpacket_msg_trunc_server(const struct test_opts *opts)
508 {
509 int fd;
510 char buf[MESSAGE_TRUNC_SZ / 2];
511 struct msghdr msg = {0};
512 struct iovec iov = {0};
513
514 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
515 if (fd < 0) {
516 perror("accept");
517 exit(EXIT_FAILURE);
518 }
519
520 control_expectln("SENDDONE");
521 iov.iov_base = buf;
522 iov.iov_len = sizeof(buf);
523 msg.msg_iov = &iov;
524 msg.msg_iovlen = 1;
525
526 ssize_t ret = recvmsg(fd, &msg, MSG_TRUNC);
527
528 if (ret != MESSAGE_TRUNC_SZ) {
529 printf("%zi\n", ret);
530 perror("MSG_TRUNC doesn't work");
531 exit(EXIT_FAILURE);
532 }
533
534 if (!(msg.msg_flags & MSG_TRUNC)) {
535 fprintf(stderr, "MSG_TRUNC expected\n");
536 exit(EXIT_FAILURE);
537 }
538
539 close(fd);
540 }
541
current_nsec(void)542 static time_t current_nsec(void)
543 {
544 struct timespec ts;
545
546 if (clock_gettime(CLOCK_REALTIME, &ts)) {
547 perror("clock_gettime(3) failed");
548 exit(EXIT_FAILURE);
549 }
550
551 return (ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec;
552 }
553
554 #define RCVTIMEO_TIMEOUT_SEC 1
555 #define READ_OVERHEAD_NSEC 250000000 /* 0.25 sec */
556
test_seqpacket_timeout_client(const struct test_opts * opts)557 static void test_seqpacket_timeout_client(const struct test_opts *opts)
558 {
559 int fd;
560 struct timeval tv;
561 char dummy;
562 time_t read_enter_ns;
563 time_t read_overhead_ns;
564
565 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
566 if (fd < 0) {
567 perror("connect");
568 exit(EXIT_FAILURE);
569 }
570
571 tv.tv_sec = RCVTIMEO_TIMEOUT_SEC;
572 tv.tv_usec = 0;
573
574 setsockopt_timeval_check(fd, SOL_SOCKET, SO_RCVTIMEO, tv,
575 "setsockopt(SO_RCVTIMEO)");
576
577 read_enter_ns = current_nsec();
578
579 if (read(fd, &dummy, sizeof(dummy)) != -1) {
580 fprintf(stderr,
581 "expected 'dummy' read(2) failure\n");
582 exit(EXIT_FAILURE);
583 }
584
585 if (errno != EAGAIN) {
586 perror("EAGAIN expected");
587 exit(EXIT_FAILURE);
588 }
589
590 read_overhead_ns = current_nsec() - read_enter_ns -
591 NSEC_PER_SEC * RCVTIMEO_TIMEOUT_SEC;
592
593 if (read_overhead_ns > READ_OVERHEAD_NSEC) {
594 fprintf(stderr,
595 "too much time in read(2), %lu > %i ns\n",
596 read_overhead_ns, READ_OVERHEAD_NSEC);
597 exit(EXIT_FAILURE);
598 }
599
600 control_writeln("WAITDONE");
601 close(fd);
602 }
603
test_seqpacket_timeout_server(const struct test_opts * opts)604 static void test_seqpacket_timeout_server(const struct test_opts *opts)
605 {
606 int fd;
607
608 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
609 if (fd < 0) {
610 perror("accept");
611 exit(EXIT_FAILURE);
612 }
613
614 control_expectln("WAITDONE");
615 close(fd);
616 }
617
test_seqpacket_bigmsg_client(const struct test_opts * opts)618 static void test_seqpacket_bigmsg_client(const struct test_opts *opts)
619 {
620 unsigned long long sock_buf_size;
621 size_t buf_size;
622 socklen_t len;
623 void *data;
624 int fd;
625
626 len = sizeof(sock_buf_size);
627
628 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
629 if (fd < 0) {
630 perror("connect");
631 exit(EXIT_FAILURE);
632 }
633
634 if (getsockopt(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
635 &sock_buf_size, &len)) {
636 perror("getsockopt");
637 exit(EXIT_FAILURE);
638 }
639
640 sock_buf_size++;
641
642 /* size_t can be < unsigned long long */
643 buf_size = (size_t)sock_buf_size;
644 if (buf_size != sock_buf_size) {
645 fprintf(stderr, "Returned BUFFER_SIZE too large\n");
646 exit(EXIT_FAILURE);
647 }
648
649 data = malloc(buf_size);
650 if (!data) {
651 perror("malloc");
652 exit(EXIT_FAILURE);
653 }
654
655 send_buf(fd, data, buf_size, 0, -EMSGSIZE);
656
657 control_writeln("CLISENT");
658
659 free(data);
660 close(fd);
661 }
662
test_seqpacket_bigmsg_server(const struct test_opts * opts)663 static void test_seqpacket_bigmsg_server(const struct test_opts *opts)
664 {
665 int fd;
666
667 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
668 if (fd < 0) {
669 perror("accept");
670 exit(EXIT_FAILURE);
671 }
672
673 control_expectln("CLISENT");
674
675 close(fd);
676 }
677
678 #define BUF_PATTERN_1 'a'
679 #define BUF_PATTERN_2 'b'
680
test_seqpacket_invalid_rec_buffer_client(const struct test_opts * opts)681 static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts)
682 {
683 int fd;
684 unsigned char *buf1;
685 unsigned char *buf2;
686 int buf_size = getpagesize() * 3;
687
688 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
689 if (fd < 0) {
690 perror("connect");
691 exit(EXIT_FAILURE);
692 }
693
694 buf1 = malloc(buf_size);
695 if (!buf1) {
696 perror("'malloc()' for 'buf1'");
697 exit(EXIT_FAILURE);
698 }
699
700 buf2 = malloc(buf_size);
701 if (!buf2) {
702 perror("'malloc()' for 'buf2'");
703 exit(EXIT_FAILURE);
704 }
705
706 memset(buf1, BUF_PATTERN_1, buf_size);
707 memset(buf2, BUF_PATTERN_2, buf_size);
708
709 send_buf(fd, buf1, buf_size, 0, buf_size);
710
711 send_buf(fd, buf2, buf_size, 0, buf_size);
712
713 close(fd);
714 }
715
test_seqpacket_invalid_rec_buffer_server(const struct test_opts * opts)716 static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts)
717 {
718 int fd;
719 unsigned char *broken_buf;
720 unsigned char *valid_buf;
721 int page_size = getpagesize();
722 int buf_size = page_size * 3;
723 ssize_t res;
724 int prot = PROT_READ | PROT_WRITE;
725 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
726 int i;
727
728 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
729 if (fd < 0) {
730 perror("accept");
731 exit(EXIT_FAILURE);
732 }
733
734 /* Setup first buffer. */
735 broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
736 if (broken_buf == MAP_FAILED) {
737 perror("mmap for 'broken_buf'");
738 exit(EXIT_FAILURE);
739 }
740
741 /* Unmap "hole" in buffer. */
742 if (munmap(broken_buf + page_size, page_size)) {
743 perror("'broken_buf' setup");
744 exit(EXIT_FAILURE);
745 }
746
747 valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0);
748 if (valid_buf == MAP_FAILED) {
749 perror("mmap for 'valid_buf'");
750 exit(EXIT_FAILURE);
751 }
752
753 /* Try to fill buffer with unmapped middle. */
754 res = read(fd, broken_buf, buf_size);
755 if (res != -1) {
756 fprintf(stderr,
757 "expected 'broken_buf' read(2) failure, got %zi\n",
758 res);
759 exit(EXIT_FAILURE);
760 }
761
762 if (errno != EFAULT) {
763 perror("unexpected errno of 'broken_buf'");
764 exit(EXIT_FAILURE);
765 }
766
767 /* Try to fill valid buffer. */
768 res = read(fd, valid_buf, buf_size);
769 if (res < 0) {
770 perror("unexpected 'valid_buf' read(2) failure");
771 exit(EXIT_FAILURE);
772 }
773
774 if (res != buf_size) {
775 fprintf(stderr,
776 "invalid 'valid_buf' read(2), expected %i, got %zi\n",
777 buf_size, res);
778 exit(EXIT_FAILURE);
779 }
780
781 for (i = 0; i < buf_size; i++) {
782 if (valid_buf[i] != BUF_PATTERN_2) {
783 fprintf(stderr,
784 "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n",
785 i, BUF_PATTERN_2, valid_buf[i]);
786 exit(EXIT_FAILURE);
787 }
788 }
789
790 /* Unmap buffers. */
791 munmap(broken_buf, page_size);
792 munmap(broken_buf + page_size * 2, page_size);
793 munmap(valid_buf, buf_size);
794 close(fd);
795 }
796
797 #define RCVLOWAT_BUF_SIZE 128
798
test_stream_poll_rcvlowat_server(const struct test_opts * opts)799 static void test_stream_poll_rcvlowat_server(const struct test_opts *opts)
800 {
801 int fd;
802 int i;
803
804 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
805 if (fd < 0) {
806 perror("accept");
807 exit(EXIT_FAILURE);
808 }
809
810 /* Send 1 byte. */
811 send_byte(fd, 1, 0);
812
813 control_writeln("SRVSENT");
814
815 /* Wait until client is ready to receive rest of data. */
816 control_expectln("CLNSENT");
817
818 for (i = 0; i < RCVLOWAT_BUF_SIZE - 1; i++)
819 send_byte(fd, 1, 0);
820
821 /* Keep socket in active state. */
822 control_expectln("POLLDONE");
823
824 close(fd);
825 }
826
test_stream_poll_rcvlowat_client(const struct test_opts * opts)827 static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
828 {
829 int lowat_val = RCVLOWAT_BUF_SIZE;
830 char buf[RCVLOWAT_BUF_SIZE];
831 struct pollfd fds;
832 short poll_flags;
833 int fd;
834
835 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
836 if (fd < 0) {
837 perror("connect");
838 exit(EXIT_FAILURE);
839 }
840
841 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
842 lowat_val, "setsockopt(SO_RCVLOWAT)");
843
844 control_expectln("SRVSENT");
845
846 /* At this point, server sent 1 byte. */
847 fds.fd = fd;
848 poll_flags = POLLIN | POLLRDNORM;
849 fds.events = poll_flags;
850
851 /* Try to wait for 1 sec. */
852 if (poll(&fds, 1, 1000) < 0) {
853 perror("poll");
854 exit(EXIT_FAILURE);
855 }
856
857 /* poll() must return nothing. */
858 if (fds.revents) {
859 fprintf(stderr, "Unexpected poll result %hx\n",
860 fds.revents);
861 exit(EXIT_FAILURE);
862 }
863
864 /* Tell server to send rest of data. */
865 control_writeln("CLNSENT");
866
867 /* Poll for data. */
868 if (poll(&fds, 1, 10000) < 0) {
869 perror("poll");
870 exit(EXIT_FAILURE);
871 }
872
873 /* Only these two bits are expected. */
874 if (fds.revents != poll_flags) {
875 fprintf(stderr, "Unexpected poll result %hx\n",
876 fds.revents);
877 exit(EXIT_FAILURE);
878 }
879
880 /* Use MSG_DONTWAIT, if call is going to wait, EAGAIN
881 * will be returned.
882 */
883 recv_buf(fd, buf, sizeof(buf), MSG_DONTWAIT, RCVLOWAT_BUF_SIZE);
884
885 control_writeln("POLLDONE");
886
887 close(fd);
888 }
889
890 #define INV_BUF_TEST_DATA_LEN 512
891
test_inv_buf_client(const struct test_opts * opts,bool stream)892 static void test_inv_buf_client(const struct test_opts *opts, bool stream)
893 {
894 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
895 ssize_t expected_ret;
896 int fd;
897
898 if (stream)
899 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
900 else
901 fd = vsock_seqpacket_connect(opts->peer_cid, opts->peer_port);
902
903 if (fd < 0) {
904 perror("connect");
905 exit(EXIT_FAILURE);
906 }
907
908 control_expectln("SENDDONE");
909
910 /* Use invalid buffer here. */
911 recv_buf(fd, NULL, sizeof(data), 0, -EFAULT);
912
913 if (stream) {
914 /* For SOCK_STREAM we must continue reading. */
915 expected_ret = sizeof(data);
916 } else {
917 /* For SOCK_SEQPACKET socket's queue must be empty. */
918 expected_ret = -EAGAIN;
919 }
920
921 recv_buf(fd, data, sizeof(data), MSG_DONTWAIT, expected_ret);
922
923 control_writeln("DONE");
924
925 close(fd);
926 }
927
test_inv_buf_server(const struct test_opts * opts,bool stream)928 static void test_inv_buf_server(const struct test_opts *opts, bool stream)
929 {
930 unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
931 int fd;
932
933 if (stream)
934 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
935 else
936 fd = vsock_seqpacket_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
937
938 if (fd < 0) {
939 perror("accept");
940 exit(EXIT_FAILURE);
941 }
942
943 send_buf(fd, data, sizeof(data), 0, sizeof(data));
944
945 control_writeln("SENDDONE");
946
947 control_expectln("DONE");
948
949 close(fd);
950 }
951
test_stream_inv_buf_client(const struct test_opts * opts)952 static void test_stream_inv_buf_client(const struct test_opts *opts)
953 {
954 test_inv_buf_client(opts, true);
955 }
956
test_stream_inv_buf_server(const struct test_opts * opts)957 static void test_stream_inv_buf_server(const struct test_opts *opts)
958 {
959 test_inv_buf_server(opts, true);
960 }
961
test_seqpacket_inv_buf_client(const struct test_opts * opts)962 static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
963 {
964 test_inv_buf_client(opts, false);
965 }
966
test_seqpacket_inv_buf_server(const struct test_opts * opts)967 static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
968 {
969 test_inv_buf_server(opts, false);
970 }
971
972 #define HELLO_STR "HELLO"
973 #define WORLD_STR "WORLD"
974
test_stream_virtio_skb_merge_client(const struct test_opts * opts)975 static void test_stream_virtio_skb_merge_client(const struct test_opts *opts)
976 {
977 int fd;
978
979 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
980 if (fd < 0) {
981 perror("connect");
982 exit(EXIT_FAILURE);
983 }
984
985 /* Send first skbuff. */
986 send_buf(fd, HELLO_STR, strlen(HELLO_STR), 0, strlen(HELLO_STR));
987
988 control_writeln("SEND0");
989 /* Peer reads part of first skbuff. */
990 control_expectln("REPLY0");
991
992 /* Send second skbuff, it will be appended to the first. */
993 send_buf(fd, WORLD_STR, strlen(WORLD_STR), 0, strlen(WORLD_STR));
994
995 control_writeln("SEND1");
996 /* Peer reads merged skbuff packet. */
997 control_expectln("REPLY1");
998
999 close(fd);
1000 }
1001
test_stream_virtio_skb_merge_server(const struct test_opts * opts)1002 static void test_stream_virtio_skb_merge_server(const struct test_opts *opts)
1003 {
1004 size_t read = 0, to_read;
1005 unsigned char buf[64];
1006 int fd;
1007
1008 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1009 if (fd < 0) {
1010 perror("accept");
1011 exit(EXIT_FAILURE);
1012 }
1013
1014 control_expectln("SEND0");
1015
1016 /* Read skbuff partially. */
1017 to_read = 2;
1018 recv_buf(fd, buf + read, to_read, 0, to_read);
1019 read += to_read;
1020
1021 control_writeln("REPLY0");
1022 control_expectln("SEND1");
1023
1024 /* Read the rest of both buffers */
1025 to_read = strlen(HELLO_STR WORLD_STR) - read;
1026 recv_buf(fd, buf + read, to_read, 0, to_read);
1027 read += to_read;
1028
1029 /* No more bytes should be there */
1030 to_read = sizeof(buf) - read;
1031 recv_buf(fd, buf + read, to_read, MSG_DONTWAIT, -EAGAIN);
1032
1033 if (memcmp(buf, HELLO_STR WORLD_STR, strlen(HELLO_STR WORLD_STR))) {
1034 fprintf(stderr, "pattern mismatch\n");
1035 exit(EXIT_FAILURE);
1036 }
1037
1038 control_writeln("REPLY1");
1039
1040 close(fd);
1041 }
1042
test_seqpacket_msg_peek_client(const struct test_opts * opts)1043 static void test_seqpacket_msg_peek_client(const struct test_opts *opts)
1044 {
1045 return test_msg_peek_client(opts, true);
1046 }
1047
test_seqpacket_msg_peek_server(const struct test_opts * opts)1048 static void test_seqpacket_msg_peek_server(const struct test_opts *opts)
1049 {
1050 return test_msg_peek_server(opts, true);
1051 }
1052
1053 static sig_atomic_t have_sigpipe;
1054
sigpipe(int signo)1055 static void sigpipe(int signo)
1056 {
1057 have_sigpipe = 1;
1058 }
1059
1060 #define SEND_SLEEP_USEC (10 * 1000)
1061
test_stream_check_sigpipe(int fd)1062 static void test_stream_check_sigpipe(int fd)
1063 {
1064 ssize_t res;
1065
1066 have_sigpipe = 0;
1067
1068 /* When the other peer calls shutdown(SHUT_RD), there is a chance that
1069 * the send() call could occur before the message carrying the close
1070 * information arrives over the transport. In such cases, the send()
1071 * might still succeed. To avoid this race, let's retry the send() call
1072 * a few times, ensuring the test is more reliable.
1073 */
1074 timeout_begin(TIMEOUT);
1075 while(1) {
1076 res = send(fd, "A", 1, 0);
1077 if (res == -1 && errno != EINTR)
1078 break;
1079
1080 /* Sleep a little before trying again to avoid flooding the
1081 * other peer and filling its receive buffer, causing
1082 * false-negative.
1083 */
1084 timeout_usleep(SEND_SLEEP_USEC);
1085 timeout_check("send");
1086 }
1087 timeout_end();
1088
1089 if (errno != EPIPE) {
1090 fprintf(stderr, "unexpected send(2) errno %d\n", errno);
1091 exit(EXIT_FAILURE);
1092 }
1093 if (!have_sigpipe) {
1094 fprintf(stderr, "SIGPIPE expected\n");
1095 exit(EXIT_FAILURE);
1096 }
1097
1098 have_sigpipe = 0;
1099
1100 timeout_begin(TIMEOUT);
1101 while(1) {
1102 res = send(fd, "A", 1, MSG_NOSIGNAL);
1103 if (res == -1 && errno != EINTR)
1104 break;
1105
1106 timeout_usleep(SEND_SLEEP_USEC);
1107 timeout_check("send");
1108 }
1109 timeout_end();
1110
1111 if (errno != EPIPE) {
1112 fprintf(stderr, "unexpected send(2) errno %d\n", errno);
1113 exit(EXIT_FAILURE);
1114 }
1115 if (have_sigpipe) {
1116 fprintf(stderr, "SIGPIPE not expected\n");
1117 exit(EXIT_FAILURE);
1118 }
1119 }
1120
test_stream_shutwr_client(const struct test_opts * opts)1121 static void test_stream_shutwr_client(const struct test_opts *opts)
1122 {
1123 int fd;
1124
1125 struct sigaction act = {
1126 .sa_handler = sigpipe,
1127 };
1128
1129 sigaction(SIGPIPE, &act, NULL);
1130
1131 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1132 if (fd < 0) {
1133 perror("connect");
1134 exit(EXIT_FAILURE);
1135 }
1136
1137 if (shutdown(fd, SHUT_WR)) {
1138 perror("shutdown");
1139 exit(EXIT_FAILURE);
1140 }
1141
1142 test_stream_check_sigpipe(fd);
1143
1144 control_writeln("CLIENTDONE");
1145
1146 close(fd);
1147 }
1148
test_stream_shutwr_server(const struct test_opts * opts)1149 static void test_stream_shutwr_server(const struct test_opts *opts)
1150 {
1151 int fd;
1152
1153 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1154 if (fd < 0) {
1155 perror("accept");
1156 exit(EXIT_FAILURE);
1157 }
1158
1159 control_expectln("CLIENTDONE");
1160
1161 close(fd);
1162 }
1163
test_stream_shutrd_client(const struct test_opts * opts)1164 static void test_stream_shutrd_client(const struct test_opts *opts)
1165 {
1166 int fd;
1167
1168 struct sigaction act = {
1169 .sa_handler = sigpipe,
1170 };
1171
1172 sigaction(SIGPIPE, &act, NULL);
1173
1174 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1175 if (fd < 0) {
1176 perror("connect");
1177 exit(EXIT_FAILURE);
1178 }
1179
1180 control_expectln("SHUTRDDONE");
1181
1182 test_stream_check_sigpipe(fd);
1183
1184 control_writeln("CLIENTDONE");
1185
1186 close(fd);
1187 }
1188
test_stream_shutrd_server(const struct test_opts * opts)1189 static void test_stream_shutrd_server(const struct test_opts *opts)
1190 {
1191 int fd;
1192
1193 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1194 if (fd < 0) {
1195 perror("accept");
1196 exit(EXIT_FAILURE);
1197 }
1198
1199 if (shutdown(fd, SHUT_RD)) {
1200 perror("shutdown");
1201 exit(EXIT_FAILURE);
1202 }
1203
1204 control_writeln("SHUTRDDONE");
1205 control_expectln("CLIENTDONE");
1206
1207 close(fd);
1208 }
1209
test_double_bind_connect_server(const struct test_opts * opts)1210 static void test_double_bind_connect_server(const struct test_opts *opts)
1211 {
1212 int listen_fd, client_fd, i;
1213 struct sockaddr_vm sa_client;
1214 socklen_t socklen_client = sizeof(sa_client);
1215
1216 listen_fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1217
1218 for (i = 0; i < 2; i++) {
1219 control_writeln("LISTENING");
1220
1221 timeout_begin(TIMEOUT);
1222 do {
1223 client_fd = accept(listen_fd, (struct sockaddr *)&sa_client,
1224 &socklen_client);
1225 timeout_check("accept");
1226 } while (client_fd < 0 && errno == EINTR);
1227 timeout_end();
1228
1229 if (client_fd < 0) {
1230 perror("accept");
1231 exit(EXIT_FAILURE);
1232 }
1233
1234 /* Waiting for remote peer to close connection */
1235 vsock_wait_remote_close(client_fd);
1236 }
1237
1238 close(listen_fd);
1239 }
1240
test_double_bind_connect_client(const struct test_opts * opts)1241 static void test_double_bind_connect_client(const struct test_opts *opts)
1242 {
1243 int i, client_fd;
1244
1245 for (i = 0; i < 2; i++) {
1246 /* Wait until server is ready to accept a new connection */
1247 control_expectln("LISTENING");
1248
1249 /* We use 'peer_port + 1' as "some" port for the 'bind()'
1250 * call. It is safe for overflow, but must be considered,
1251 * when running multiple test applications simultaneously
1252 * where 'peer-port' argument differs by 1.
1253 */
1254 client_fd = vsock_bind_connect(opts->peer_cid, opts->peer_port,
1255 opts->peer_port + 1, SOCK_STREAM);
1256
1257 close(client_fd);
1258 }
1259 }
1260
1261 #define MSG_BUF_IOCTL_LEN 64
test_unsent_bytes_server(const struct test_opts * opts,int type)1262 static void test_unsent_bytes_server(const struct test_opts *opts, int type)
1263 {
1264 unsigned char buf[MSG_BUF_IOCTL_LEN];
1265 int client_fd;
1266
1267 client_fd = vsock_accept(VMADDR_CID_ANY, opts->peer_port, NULL, type);
1268 if (client_fd < 0) {
1269 perror("accept");
1270 exit(EXIT_FAILURE);
1271 }
1272
1273 recv_buf(client_fd, buf, sizeof(buf), 0, sizeof(buf));
1274 control_writeln("RECEIVED");
1275
1276 close(client_fd);
1277 }
1278
test_unsent_bytes_client(const struct test_opts * opts,int type)1279 static void test_unsent_bytes_client(const struct test_opts *opts, int type)
1280 {
1281 unsigned char buf[MSG_BUF_IOCTL_LEN];
1282 int fd;
1283
1284 fd = vsock_connect(opts->peer_cid, opts->peer_port, type);
1285 if (fd < 0) {
1286 perror("connect");
1287 exit(EXIT_FAILURE);
1288 }
1289
1290 for (int i = 0; i < sizeof(buf); i++)
1291 buf[i] = rand() & 0xFF;
1292
1293 send_buf(fd, buf, sizeof(buf), 0, sizeof(buf));
1294 control_expectln("RECEIVED");
1295
1296 /* SIOCOUTQ isn't guaranteed to instantly track sent data. Even though
1297 * the "RECEIVED" message means that the other side has received the
1298 * data, there can be a delay in our kernel before updating the "unsent
1299 * bytes" counter. vsock_wait_sent() will repeat SIOCOUTQ until it
1300 * returns 0.
1301 */
1302 if (!vsock_wait_sent(fd))
1303 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1304
1305 close(fd);
1306 }
1307
test_stream_unsent_bytes_client(const struct test_opts * opts)1308 static void test_stream_unsent_bytes_client(const struct test_opts *opts)
1309 {
1310 test_unsent_bytes_client(opts, SOCK_STREAM);
1311 }
1312
test_stream_unsent_bytes_server(const struct test_opts * opts)1313 static void test_stream_unsent_bytes_server(const struct test_opts *opts)
1314 {
1315 test_unsent_bytes_server(opts, SOCK_STREAM);
1316 }
1317
test_seqpacket_unsent_bytes_client(const struct test_opts * opts)1318 static void test_seqpacket_unsent_bytes_client(const struct test_opts *opts)
1319 {
1320 test_unsent_bytes_client(opts, SOCK_SEQPACKET);
1321 }
1322
test_seqpacket_unsent_bytes_server(const struct test_opts * opts)1323 static void test_seqpacket_unsent_bytes_server(const struct test_opts *opts)
1324 {
1325 test_unsent_bytes_server(opts, SOCK_SEQPACKET);
1326 }
1327
1328 #define RCVLOWAT_CREDIT_UPD_BUF_SIZE (1024 * 128)
1329 /* This define is the same as in 'include/linux/virtio_vsock.h':
1330 * it is used to decide when to send credit update message during
1331 * reading from rx queue of a socket. Value and its usage in
1332 * kernel is important for this test.
1333 */
1334 #define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
1335
test_stream_rcvlowat_def_cred_upd_client(const struct test_opts * opts)1336 static void test_stream_rcvlowat_def_cred_upd_client(const struct test_opts *opts)
1337 {
1338 size_t buf_size;
1339 void *buf;
1340 int fd;
1341
1342 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1343 if (fd < 0) {
1344 perror("connect");
1345 exit(EXIT_FAILURE);
1346 }
1347
1348 /* Send 1 byte more than peer's buffer size. */
1349 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE + 1;
1350
1351 buf = malloc(buf_size);
1352 if (!buf) {
1353 perror("malloc");
1354 exit(EXIT_FAILURE);
1355 }
1356
1357 /* Wait until peer sets needed buffer size. */
1358 recv_byte(fd, 1, 0);
1359
1360 if (send(fd, buf, buf_size, 0) != buf_size) {
1361 perror("send failed");
1362 exit(EXIT_FAILURE);
1363 }
1364
1365 free(buf);
1366 close(fd);
1367 }
1368
test_stream_credit_update_test(const struct test_opts * opts,bool low_rx_bytes_test)1369 static void test_stream_credit_update_test(const struct test_opts *opts,
1370 bool low_rx_bytes_test)
1371 {
1372 int recv_buf_size;
1373 struct pollfd fds;
1374 size_t buf_size;
1375 unsigned long long sock_buf_size;
1376 void *buf;
1377 int fd;
1378
1379 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1380 if (fd < 0) {
1381 perror("accept");
1382 exit(EXIT_FAILURE);
1383 }
1384
1385 buf_size = RCVLOWAT_CREDIT_UPD_BUF_SIZE;
1386
1387 /* size_t can be < unsigned long long */
1388 sock_buf_size = buf_size;
1389
1390 setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
1391 sock_buf_size,
1392 "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
1393
1394 if (low_rx_bytes_test) {
1395 /* Set new SO_RCVLOWAT here. This enables sending credit
1396 * update when number of bytes if our rx queue become <
1397 * SO_RCVLOWAT value.
1398 */
1399 recv_buf_size = 1 + VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1400
1401 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1402 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1403 }
1404
1405 /* Send one dummy byte here, because 'setsockopt()' above also
1406 * sends special packet which tells sender to update our buffer
1407 * size. This 'send_byte()' will serialize such packet with data
1408 * reads in a loop below. Sender starts transmission only when
1409 * it receives this single byte.
1410 */
1411 send_byte(fd, 1, 0);
1412
1413 buf = malloc(buf_size);
1414 if (!buf) {
1415 perror("malloc");
1416 exit(EXIT_FAILURE);
1417 }
1418
1419 /* Wait until there will be 128KB of data in rx queue. */
1420 while (1) {
1421 ssize_t res;
1422
1423 res = recv(fd, buf, buf_size, MSG_PEEK);
1424 if (res == buf_size)
1425 break;
1426
1427 if (res <= 0) {
1428 fprintf(stderr, "unexpected 'recv()' return: %zi\n", res);
1429 exit(EXIT_FAILURE);
1430 }
1431 }
1432
1433 /* There is 128KB of data in the socket's rx queue, dequeue first
1434 * 64KB, credit update is sent if 'low_rx_bytes_test' == true.
1435 * Otherwise, credit update is sent in 'if (!low_rx_bytes_test)'.
1436 */
1437 recv_buf_size = VIRTIO_VSOCK_MAX_PKT_BUF_SIZE;
1438 recv_buf(fd, buf, recv_buf_size, 0, recv_buf_size);
1439
1440 if (!low_rx_bytes_test) {
1441 recv_buf_size++;
1442
1443 /* Updating SO_RCVLOWAT will send credit update. */
1444 setsockopt_int_check(fd, SOL_SOCKET, SO_RCVLOWAT,
1445 recv_buf_size, "setsockopt(SO_RCVLOWAT)");
1446 }
1447
1448 fds.fd = fd;
1449 fds.events = POLLIN | POLLRDNORM | POLLERR |
1450 POLLRDHUP | POLLHUP;
1451
1452 /* This 'poll()' will return once we receive last byte
1453 * sent by client.
1454 */
1455 if (poll(&fds, 1, -1) < 0) {
1456 perror("poll");
1457 exit(EXIT_FAILURE);
1458 }
1459
1460 if (fds.revents & POLLERR) {
1461 fprintf(stderr, "'poll()' error\n");
1462 exit(EXIT_FAILURE);
1463 }
1464
1465 if (fds.revents & (POLLIN | POLLRDNORM)) {
1466 recv_buf(fd, buf, recv_buf_size, MSG_DONTWAIT, recv_buf_size);
1467 } else {
1468 /* These flags must be set, as there is at
1469 * least 64KB of data ready to read.
1470 */
1471 fprintf(stderr, "POLLIN | POLLRDNORM expected\n");
1472 exit(EXIT_FAILURE);
1473 }
1474
1475 free(buf);
1476 close(fd);
1477 }
1478
test_stream_cred_upd_on_low_rx_bytes(const struct test_opts * opts)1479 static void test_stream_cred_upd_on_low_rx_bytes(const struct test_opts *opts)
1480 {
1481 test_stream_credit_update_test(opts, true);
1482 }
1483
test_stream_cred_upd_on_set_rcvlowat(const struct test_opts * opts)1484 static void test_stream_cred_upd_on_set_rcvlowat(const struct test_opts *opts)
1485 {
1486 test_stream_credit_update_test(opts, false);
1487 }
1488
1489 /* The goal of test leak_acceptq is to stress the race between connect() and
1490 * close(listener). Implementation of client/server loops boils down to:
1491 *
1492 * client server
1493 * ------ ------
1494 * write(CONTINUE)
1495 * expect(CONTINUE)
1496 * listen()
1497 * write(LISTENING)
1498 * expect(LISTENING)
1499 * connect() close()
1500 */
1501 #define ACCEPTQ_LEAK_RACE_TIMEOUT 2 /* seconds */
1502
test_stream_leak_acceptq_client(const struct test_opts * opts)1503 static void test_stream_leak_acceptq_client(const struct test_opts *opts)
1504 {
1505 time_t tout;
1506 int fd;
1507
1508 tout = current_nsec() + ACCEPTQ_LEAK_RACE_TIMEOUT * NSEC_PER_SEC;
1509 do {
1510 control_writeulong(CONTROL_CONTINUE);
1511
1512 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1513 if (fd >= 0)
1514 close(fd);
1515 } while (current_nsec() < tout);
1516
1517 control_writeulong(CONTROL_DONE);
1518 }
1519
1520 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_leak_acceptq_server(const struct test_opts * opts)1521 static void test_stream_leak_acceptq_server(const struct test_opts *opts)
1522 {
1523 int fd;
1524
1525 while (control_readulong() == CONTROL_CONTINUE) {
1526 fd = vsock_stream_listen(VMADDR_CID_ANY, opts->peer_port);
1527 control_writeln("LISTENING");
1528 close(fd);
1529 }
1530 }
1531
1532 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_msgzcopy_leak_errq_client(const struct test_opts * opts)1533 static void test_stream_msgzcopy_leak_errq_client(const struct test_opts *opts)
1534 {
1535 struct pollfd fds = { 0 };
1536 int fd;
1537
1538 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1539 if (fd < 0) {
1540 perror("connect");
1541 exit(EXIT_FAILURE);
1542 }
1543
1544 enable_so_zerocopy_check(fd);
1545 send_byte(fd, 1, MSG_ZEROCOPY);
1546
1547 fds.fd = fd;
1548 fds.events = 0;
1549 if (poll(&fds, 1, -1) < 0) {
1550 perror("poll");
1551 exit(EXIT_FAILURE);
1552 }
1553
1554 close(fd);
1555 }
1556
test_stream_msgzcopy_leak_errq_server(const struct test_opts * opts)1557 static void test_stream_msgzcopy_leak_errq_server(const struct test_opts *opts)
1558 {
1559 int fd;
1560
1561 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1562 if (fd < 0) {
1563 perror("accept");
1564 exit(EXIT_FAILURE);
1565 }
1566
1567 recv_byte(fd, 1, 0);
1568 vsock_wait_remote_close(fd);
1569 close(fd);
1570 }
1571
1572 /* Test msgzcopy_leak_zcskb is meant to exercise sendmsg() error handling path,
1573 * that might leak an skb. The idea is to fail virtio_transport_init_zcopy_skb()
1574 * by hitting net.core.optmem_max limit in sock_omalloc(), specifically
1575 *
1576 * vsock_connectible_sendmsg
1577 * virtio_transport_stream_enqueue
1578 * virtio_transport_send_pkt_info
1579 * virtio_transport_init_zcopy_skb
1580 * . msg_zerocopy_realloc
1581 * . msg_zerocopy_alloc
1582 * . sock_omalloc
1583 * . sk_omem_alloc + size > sysctl_optmem_max
1584 * return -ENOMEM
1585 *
1586 * We abuse the implementation detail of net/socket.c:____sys_sendmsg().
1587 * sk_omem_alloc can be precisely bumped by sock_kmalloc(), as it is used to
1588 * fetch user-provided control data.
1589 *
1590 * While this approach works for now, it relies on assumptions regarding the
1591 * implementation and configuration (for example, order of net.core.optmem_max
1592 * can not exceed MAX_PAGE_ORDER), which may not hold in the future. A more
1593 * resilient testing could be implemented by leveraging the Fault injection
1594 * framework (CONFIG_FAULT_INJECTION), e.g.
1595 *
1596 * client# echo N > /sys/kernel/debug/failslab/ignore-gfp-wait
1597 * client# echo 0 > /sys/kernel/debug/failslab/verbose
1598 *
1599 * void client(const struct test_opts *opts)
1600 * {
1601 * char buf[16];
1602 * int f, s, i;
1603 *
1604 * f = open("/proc/self/fail-nth", O_WRONLY);
1605 *
1606 * for (i = 1; i < 32; i++) {
1607 * control_writeulong(CONTROL_CONTINUE);
1608 *
1609 * s = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1610 * enable_so_zerocopy_check(s);
1611 *
1612 * sprintf(buf, "%d", i);
1613 * write(f, buf, strlen(buf));
1614 *
1615 * send(s, &(char){ 0 }, 1, MSG_ZEROCOPY);
1616 *
1617 * write(f, "0", 1);
1618 * close(s);
1619 * }
1620 *
1621 * control_writeulong(CONTROL_DONE);
1622 * close(f);
1623 * }
1624 *
1625 * void server(const struct test_opts *opts)
1626 * {
1627 * int fd;
1628 *
1629 * while (control_readulong() == CONTROL_CONTINUE) {
1630 * fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1631 * vsock_wait_remote_close(fd);
1632 * close(fd);
1633 * }
1634 * }
1635 *
1636 * Refer to Documentation/fault-injection/fault-injection.rst.
1637 */
1638 #define MAX_PAGE_ORDER 10 /* usually */
1639 #define PAGE_SIZE 4096
1640
1641 /* Test for a memory leak. User is expected to run kmemleak scan, see README. */
test_stream_msgzcopy_leak_zcskb_client(const struct test_opts * opts)1642 static void test_stream_msgzcopy_leak_zcskb_client(const struct test_opts *opts)
1643 {
1644 size_t optmem_max, ctl_len, chunk_size;
1645 struct msghdr msg = { 0 };
1646 struct iovec iov;
1647 char *chunk;
1648 int fd, res;
1649 FILE *f;
1650
1651 f = fopen("/proc/sys/net/core/optmem_max", "r");
1652 if (!f) {
1653 perror("fopen(optmem_max)");
1654 exit(EXIT_FAILURE);
1655 }
1656
1657 if (fscanf(f, "%zu", &optmem_max) != 1) {
1658 fprintf(stderr, "fscanf(optmem_max) failed\n");
1659 exit(EXIT_FAILURE);
1660 }
1661
1662 fclose(f);
1663
1664 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1665 if (fd < 0) {
1666 perror("connect");
1667 exit(EXIT_FAILURE);
1668 }
1669
1670 enable_so_zerocopy_check(fd);
1671
1672 ctl_len = optmem_max - 1;
1673 if (ctl_len > PAGE_SIZE << MAX_PAGE_ORDER) {
1674 fprintf(stderr, "Try with net.core.optmem_max = 100000\n");
1675 exit(EXIT_FAILURE);
1676 }
1677
1678 chunk_size = CMSG_SPACE(ctl_len);
1679 chunk = malloc(chunk_size);
1680 if (!chunk) {
1681 perror("malloc");
1682 exit(EXIT_FAILURE);
1683 }
1684 memset(chunk, 0, chunk_size);
1685
1686 iov.iov_base = &(char){ 0 };
1687 iov.iov_len = 1;
1688
1689 msg.msg_iov = &iov;
1690 msg.msg_iovlen = 1;
1691 msg.msg_control = chunk;
1692 msg.msg_controllen = ctl_len;
1693
1694 errno = 0;
1695 res = sendmsg(fd, &msg, MSG_ZEROCOPY);
1696 if (res >= 0 || errno != ENOMEM) {
1697 fprintf(stderr, "Expected ENOMEM, got errno=%d res=%d\n",
1698 errno, res);
1699 exit(EXIT_FAILURE);
1700 }
1701
1702 close(fd);
1703 }
1704
test_stream_msgzcopy_leak_zcskb_server(const struct test_opts * opts)1705 static void test_stream_msgzcopy_leak_zcskb_server(const struct test_opts *opts)
1706 {
1707 int fd;
1708
1709 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1710 if (fd < 0) {
1711 perror("accept");
1712 exit(EXIT_FAILURE);
1713 }
1714
1715 vsock_wait_remote_close(fd);
1716 close(fd);
1717 }
1718
1719 #define MAX_PORT_RETRIES 24 /* net/vmw_vsock/af_vsock.c */
1720
1721 /* Test attempts to trigger a transport release for an unbound socket. This can
1722 * lead to a reference count mishandling.
1723 */
test_stream_transport_uaf_client(const struct test_opts * opts)1724 static void test_stream_transport_uaf_client(const struct test_opts *opts)
1725 {
1726 int sockets[MAX_PORT_RETRIES];
1727 struct sockaddr_vm addr;
1728 int fd, i, alen;
1729
1730 fd = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, SOCK_STREAM);
1731
1732 alen = sizeof(addr);
1733 if (getsockname(fd, (struct sockaddr *)&addr, &alen)) {
1734 perror("getsockname");
1735 exit(EXIT_FAILURE);
1736 }
1737
1738 for (i = 0; i < MAX_PORT_RETRIES; ++i)
1739 sockets[i] = vsock_bind(VMADDR_CID_ANY, ++addr.svm_port,
1740 SOCK_STREAM);
1741
1742 close(fd);
1743 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1744 if (fd < 0) {
1745 perror("socket");
1746 exit(EXIT_FAILURE);
1747 }
1748
1749 if (!vsock_connect_fd(fd, addr.svm_cid, addr.svm_port)) {
1750 perror("Unexpected connect() #1 success");
1751 exit(EXIT_FAILURE);
1752 }
1753
1754 /* Vulnerable system may crash now. */
1755 if (!vsock_connect_fd(fd, VMADDR_CID_HOST, VMADDR_PORT_ANY)) {
1756 perror("Unexpected connect() #2 success");
1757 exit(EXIT_FAILURE);
1758 }
1759
1760 close(fd);
1761 while (i--)
1762 close(sockets[i]);
1763
1764 control_writeln("DONE");
1765 }
1766
test_stream_transport_uaf_server(const struct test_opts * opts)1767 static void test_stream_transport_uaf_server(const struct test_opts *opts)
1768 {
1769 control_expectln("DONE");
1770 }
1771
test_stream_connect_retry_client(const struct test_opts * opts)1772 static void test_stream_connect_retry_client(const struct test_opts *opts)
1773 {
1774 int fd;
1775
1776 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1777 if (fd < 0) {
1778 perror("socket");
1779 exit(EXIT_FAILURE);
1780 }
1781
1782 if (!vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1783 fprintf(stderr, "Unexpected connect() #1 success\n");
1784 exit(EXIT_FAILURE);
1785 }
1786
1787 control_writeln("LISTEN");
1788 control_expectln("LISTENING");
1789
1790 if (vsock_connect_fd(fd, opts->peer_cid, opts->peer_port)) {
1791 perror("connect() #2");
1792 exit(EXIT_FAILURE);
1793 }
1794
1795 close(fd);
1796 }
1797
test_stream_connect_retry_server(const struct test_opts * opts)1798 static void test_stream_connect_retry_server(const struct test_opts *opts)
1799 {
1800 int fd;
1801
1802 control_expectln("LISTEN");
1803
1804 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1805 if (fd < 0) {
1806 perror("accept");
1807 exit(EXIT_FAILURE);
1808 }
1809
1810 vsock_wait_remote_close(fd);
1811 close(fd);
1812 }
1813
test_stream_linger_client(const struct test_opts * opts)1814 static void test_stream_linger_client(const struct test_opts *opts)
1815 {
1816 int fd;
1817
1818 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1819 if (fd < 0) {
1820 perror("connect");
1821 exit(EXIT_FAILURE);
1822 }
1823
1824 enable_so_linger(fd, 1);
1825 close(fd);
1826 }
1827
test_stream_linger_server(const struct test_opts * opts)1828 static void test_stream_linger_server(const struct test_opts *opts)
1829 {
1830 int fd;
1831
1832 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1833 if (fd < 0) {
1834 perror("accept");
1835 exit(EXIT_FAILURE);
1836 }
1837
1838 vsock_wait_remote_close(fd);
1839 close(fd);
1840 }
1841
1842 /* Half of the default to not risk timing out the control channel */
1843 #define LINGER_TIMEOUT (TIMEOUT / 2)
1844
test_stream_nolinger_client(const struct test_opts * opts)1845 static void test_stream_nolinger_client(const struct test_opts *opts)
1846 {
1847 bool waited;
1848 time_t ns;
1849 int fd;
1850
1851 fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
1852 if (fd < 0) {
1853 perror("connect");
1854 exit(EXIT_FAILURE);
1855 }
1856
1857 enable_so_linger(fd, LINGER_TIMEOUT);
1858 send_byte(fd, 1, 0); /* Left unread to expose incorrect behaviour. */
1859 waited = vsock_wait_sent(fd);
1860
1861 ns = current_nsec();
1862 close(fd);
1863 ns = current_nsec() - ns;
1864
1865 if (!waited) {
1866 fprintf(stderr, "Test skipped, SIOCOUTQ not supported.\n");
1867 } else if (DIV_ROUND_UP(ns, NSEC_PER_SEC) >= LINGER_TIMEOUT) {
1868 fprintf(stderr, "Unexpected lingering\n");
1869 exit(EXIT_FAILURE);
1870 }
1871
1872 control_writeln("DONE");
1873 }
1874
test_stream_nolinger_server(const struct test_opts * opts)1875 static void test_stream_nolinger_server(const struct test_opts *opts)
1876 {
1877 int fd;
1878
1879 fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
1880 if (fd < 0) {
1881 perror("accept");
1882 exit(EXIT_FAILURE);
1883 }
1884
1885 control_expectln("DONE");
1886 close(fd);
1887 }
1888
1889 static struct test_case test_cases[] = {
1890 {
1891 .name = "SOCK_STREAM connection reset",
1892 .run_client = test_stream_connection_reset,
1893 },
1894 {
1895 .name = "SOCK_STREAM bind only",
1896 .run_client = test_stream_bind_only_client,
1897 .run_server = test_stream_bind_only_server,
1898 },
1899 {
1900 .name = "SOCK_STREAM client close",
1901 .run_client = test_stream_client_close_client,
1902 .run_server = test_stream_client_close_server,
1903 },
1904 {
1905 .name = "SOCK_STREAM server close",
1906 .run_client = test_stream_server_close_client,
1907 .run_server = test_stream_server_close_server,
1908 },
1909 {
1910 .name = "SOCK_STREAM multiple connections",
1911 .run_client = test_stream_multiconn_client,
1912 .run_server = test_stream_multiconn_server,
1913 },
1914 {
1915 .name = "SOCK_STREAM MSG_PEEK",
1916 .run_client = test_stream_msg_peek_client,
1917 .run_server = test_stream_msg_peek_server,
1918 },
1919 {
1920 .name = "SOCK_SEQPACKET msg bounds",
1921 .run_client = test_seqpacket_msg_bounds_client,
1922 .run_server = test_seqpacket_msg_bounds_server,
1923 },
1924 {
1925 .name = "SOCK_SEQPACKET MSG_TRUNC flag",
1926 .run_client = test_seqpacket_msg_trunc_client,
1927 .run_server = test_seqpacket_msg_trunc_server,
1928 },
1929 {
1930 .name = "SOCK_SEQPACKET timeout",
1931 .run_client = test_seqpacket_timeout_client,
1932 .run_server = test_seqpacket_timeout_server,
1933 },
1934 {
1935 .name = "SOCK_SEQPACKET invalid receive buffer",
1936 .run_client = test_seqpacket_invalid_rec_buffer_client,
1937 .run_server = test_seqpacket_invalid_rec_buffer_server,
1938 },
1939 {
1940 .name = "SOCK_STREAM poll() + SO_RCVLOWAT",
1941 .run_client = test_stream_poll_rcvlowat_client,
1942 .run_server = test_stream_poll_rcvlowat_server,
1943 },
1944 {
1945 .name = "SOCK_SEQPACKET big message",
1946 .run_client = test_seqpacket_bigmsg_client,
1947 .run_server = test_seqpacket_bigmsg_server,
1948 },
1949 {
1950 .name = "SOCK_STREAM test invalid buffer",
1951 .run_client = test_stream_inv_buf_client,
1952 .run_server = test_stream_inv_buf_server,
1953 },
1954 {
1955 .name = "SOCK_SEQPACKET test invalid buffer",
1956 .run_client = test_seqpacket_inv_buf_client,
1957 .run_server = test_seqpacket_inv_buf_server,
1958 },
1959 {
1960 .name = "SOCK_STREAM virtio skb merge",
1961 .run_client = test_stream_virtio_skb_merge_client,
1962 .run_server = test_stream_virtio_skb_merge_server,
1963 },
1964 {
1965 .name = "SOCK_SEQPACKET MSG_PEEK",
1966 .run_client = test_seqpacket_msg_peek_client,
1967 .run_server = test_seqpacket_msg_peek_server,
1968 },
1969 {
1970 .name = "SOCK_STREAM SHUT_WR",
1971 .run_client = test_stream_shutwr_client,
1972 .run_server = test_stream_shutwr_server,
1973 },
1974 {
1975 .name = "SOCK_STREAM SHUT_RD",
1976 .run_client = test_stream_shutrd_client,
1977 .run_server = test_stream_shutrd_server,
1978 },
1979 {
1980 .name = "SOCK_STREAM MSG_ZEROCOPY",
1981 .run_client = test_stream_msgzcopy_client,
1982 .run_server = test_stream_msgzcopy_server,
1983 },
1984 {
1985 .name = "SOCK_SEQPACKET MSG_ZEROCOPY",
1986 .run_client = test_seqpacket_msgzcopy_client,
1987 .run_server = test_seqpacket_msgzcopy_server,
1988 },
1989 {
1990 .name = "SOCK_STREAM MSG_ZEROCOPY empty MSG_ERRQUEUE",
1991 .run_client = test_stream_msgzcopy_empty_errq_client,
1992 .run_server = test_stream_msgzcopy_empty_errq_server,
1993 },
1994 {
1995 .name = "SOCK_STREAM double bind connect",
1996 .run_client = test_double_bind_connect_client,
1997 .run_server = test_double_bind_connect_server,
1998 },
1999 {
2000 .name = "SOCK_STREAM virtio credit update + SO_RCVLOWAT",
2001 .run_client = test_stream_rcvlowat_def_cred_upd_client,
2002 .run_server = test_stream_cred_upd_on_set_rcvlowat,
2003 },
2004 {
2005 .name = "SOCK_STREAM virtio credit update + low rx_bytes",
2006 .run_client = test_stream_rcvlowat_def_cred_upd_client,
2007 .run_server = test_stream_cred_upd_on_low_rx_bytes,
2008 },
2009 {
2010 .name = "SOCK_STREAM ioctl(SIOCOUTQ) 0 unsent bytes",
2011 .run_client = test_stream_unsent_bytes_client,
2012 .run_server = test_stream_unsent_bytes_server,
2013 },
2014 {
2015 .name = "SOCK_SEQPACKET ioctl(SIOCOUTQ) 0 unsent bytes",
2016 .run_client = test_seqpacket_unsent_bytes_client,
2017 .run_server = test_seqpacket_unsent_bytes_server,
2018 },
2019 {
2020 .name = "SOCK_STREAM leak accept queue",
2021 .run_client = test_stream_leak_acceptq_client,
2022 .run_server = test_stream_leak_acceptq_server,
2023 },
2024 {
2025 .name = "SOCK_STREAM MSG_ZEROCOPY leak MSG_ERRQUEUE",
2026 .run_client = test_stream_msgzcopy_leak_errq_client,
2027 .run_server = test_stream_msgzcopy_leak_errq_server,
2028 },
2029 {
2030 .name = "SOCK_STREAM MSG_ZEROCOPY leak completion skb",
2031 .run_client = test_stream_msgzcopy_leak_zcskb_client,
2032 .run_server = test_stream_msgzcopy_leak_zcskb_server,
2033 },
2034 {
2035 .name = "SOCK_STREAM transport release use-after-free",
2036 .run_client = test_stream_transport_uaf_client,
2037 .run_server = test_stream_transport_uaf_server,
2038 },
2039 {
2040 .name = "SOCK_STREAM retry failed connect()",
2041 .run_client = test_stream_connect_retry_client,
2042 .run_server = test_stream_connect_retry_server,
2043 },
2044 {
2045 .name = "SOCK_STREAM SO_LINGER null-ptr-deref",
2046 .run_client = test_stream_linger_client,
2047 .run_server = test_stream_linger_server,
2048 },
2049 {
2050 .name = "SOCK_STREAM SO_LINGER close() on unread",
2051 .run_client = test_stream_nolinger_client,
2052 .run_server = test_stream_nolinger_server,
2053 },
2054 {},
2055 };
2056
2057 static const char optstring[] = "";
2058 static const struct option longopts[] = {
2059 {
2060 .name = "control-host",
2061 .has_arg = required_argument,
2062 .val = 'H',
2063 },
2064 {
2065 .name = "control-port",
2066 .has_arg = required_argument,
2067 .val = 'P',
2068 },
2069 {
2070 .name = "mode",
2071 .has_arg = required_argument,
2072 .val = 'm',
2073 },
2074 {
2075 .name = "peer-cid",
2076 .has_arg = required_argument,
2077 .val = 'p',
2078 },
2079 {
2080 .name = "peer-port",
2081 .has_arg = required_argument,
2082 .val = 'q',
2083 },
2084 {
2085 .name = "list",
2086 .has_arg = no_argument,
2087 .val = 'l',
2088 },
2089 {
2090 .name = "skip",
2091 .has_arg = required_argument,
2092 .val = 's',
2093 },
2094 {
2095 .name = "pick",
2096 .has_arg = required_argument,
2097 .val = 't',
2098 },
2099 {
2100 .name = "help",
2101 .has_arg = no_argument,
2102 .val = '?',
2103 },
2104 {},
2105 };
2106
usage(void)2107 static void usage(void)
2108 {
2109 fprintf(stderr, "Usage: vsock_test [--help] [--control-host=<host>] --control-port=<port> --mode=client|server --peer-cid=<cid> [--peer-port=<port>] [--list] [--skip=<test_id>]\n"
2110 "\n"
2111 " Server: vsock_test --control-port=1234 --mode=server --peer-cid=3\n"
2112 " Client: vsock_test --control-host=192.168.0.1 --control-port=1234 --mode=client --peer-cid=2\n"
2113 "\n"
2114 "Run vsock.ko tests. Must be launched in both guest\n"
2115 "and host. One side must use --mode=client and\n"
2116 "the other side must use --mode=server.\n"
2117 "\n"
2118 "A TCP control socket connection is used to coordinate tests\n"
2119 "between the client and the server. The server requires a\n"
2120 "listen address and the client requires an address to\n"
2121 "connect to.\n"
2122 "\n"
2123 "The CID of the other side must be given with --peer-cid=<cid>.\n"
2124 "During the test, two AF_VSOCK ports will be used: the port\n"
2125 "specified with --peer-port=<port> (or the default port)\n"
2126 "and the next one.\n"
2127 "\n"
2128 "Options:\n"
2129 " --help This help message\n"
2130 " --control-host <host> Server IP address to connect to\n"
2131 " --control-port <port> Server port to listen on/connect to\n"
2132 " --mode client|server Server or client mode\n"
2133 " --peer-cid <cid> CID of the other side\n"
2134 " --peer-port <port> AF_VSOCK port used for the test [default: %d]\n"
2135 " --list List of tests that will be executed\n"
2136 " --pick <test_id> Test ID to execute selectively;\n"
2137 " use multiple --pick options to select more tests\n"
2138 " --skip <test_id> Test ID to skip;\n"
2139 " use multiple --skip options to skip more tests\n",
2140 DEFAULT_PEER_PORT
2141 );
2142 exit(EXIT_FAILURE);
2143 }
2144
main(int argc,char ** argv)2145 int main(int argc, char **argv)
2146 {
2147 const char *control_host = NULL;
2148 const char *control_port = NULL;
2149 struct test_opts opts = {
2150 .mode = TEST_MODE_UNSET,
2151 .peer_cid = VMADDR_CID_ANY,
2152 .peer_port = DEFAULT_PEER_PORT,
2153 };
2154
2155 srand(time(NULL));
2156 init_signals();
2157
2158 for (;;) {
2159 int opt = getopt_long(argc, argv, optstring, longopts, NULL);
2160
2161 if (opt == -1)
2162 break;
2163
2164 switch (opt) {
2165 case 'H':
2166 control_host = optarg;
2167 break;
2168 case 'm':
2169 if (strcmp(optarg, "client") == 0)
2170 opts.mode = TEST_MODE_CLIENT;
2171 else if (strcmp(optarg, "server") == 0)
2172 opts.mode = TEST_MODE_SERVER;
2173 else {
2174 fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
2175 return EXIT_FAILURE;
2176 }
2177 break;
2178 case 'p':
2179 opts.peer_cid = parse_cid(optarg);
2180 break;
2181 case 'q':
2182 opts.peer_port = parse_port(optarg);
2183 break;
2184 case 'P':
2185 control_port = optarg;
2186 break;
2187 case 'l':
2188 list_tests(test_cases);
2189 break;
2190 case 's':
2191 skip_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2192 optarg);
2193 break;
2194 case 't':
2195 pick_test(test_cases, ARRAY_SIZE(test_cases) - 1,
2196 optarg);
2197 break;
2198 case '?':
2199 default:
2200 usage();
2201 }
2202 }
2203
2204 if (!control_port)
2205 usage();
2206 if (opts.mode == TEST_MODE_UNSET)
2207 usage();
2208 if (opts.peer_cid == VMADDR_CID_ANY)
2209 usage();
2210
2211 if (!control_host) {
2212 if (opts.mode != TEST_MODE_SERVER)
2213 usage();
2214 control_host = "0.0.0.0";
2215 }
2216
2217 control_init(control_host, control_port,
2218 opts.mode == TEST_MODE_SERVER);
2219
2220 run_tests(test_cases, &opts);
2221
2222 control_cleanup();
2223 return EXIT_SUCCESS;
2224 }
2225