Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

af_vsock: SOCK_SEQPACKET broken buffer test

Add test where sender sends two message, each with own
data pattern. Reader tries to read first to broken buffer:
it has three pages size, but middle page is unmapped. Then,
reader tries to read second message to valid buffer. Test
checks, that uncopied part of first message was dropped
and thus not copied as part of second message.

Signed-off-by: Krasnov Arseniy Vladimirovich <AVKrasnov@sberdevices.ru>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Krasnov Arseniy Vladimirovich and committed by
David S. Miller
e89600eb efb3719f

+131
+131
tools/testing/vsock/vsock_test.c
··· 17 17 #include <sys/types.h> 18 18 #include <sys/socket.h> 19 19 #include <time.h> 20 + #include <sys/mman.h> 20 21 21 22 #include "timeout.h" 22 23 #include "control.h" ··· 471 470 close(fd); 472 471 } 473 472 473 + #define BUF_PATTERN_1 'a' 474 + #define BUF_PATTERN_2 'b' 475 + 476 + static void test_seqpacket_invalid_rec_buffer_client(const struct test_opts *opts) 477 + { 478 + int fd; 479 + unsigned char *buf1; 480 + unsigned char *buf2; 481 + int buf_size = getpagesize() * 3; 482 + 483 + fd = vsock_seqpacket_connect(opts->peer_cid, 1234); 484 + if (fd < 0) { 485 + perror("connect"); 486 + exit(EXIT_FAILURE); 487 + } 488 + 489 + buf1 = malloc(buf_size); 490 + if (!buf1) { 491 + perror("'malloc()' for 'buf1'"); 492 + exit(EXIT_FAILURE); 493 + } 494 + 495 + buf2 = malloc(buf_size); 496 + if (!buf2) { 497 + perror("'malloc()' for 'buf2'"); 498 + exit(EXIT_FAILURE); 499 + } 500 + 501 + memset(buf1, BUF_PATTERN_1, buf_size); 502 + memset(buf2, BUF_PATTERN_2, buf_size); 503 + 504 + if (send(fd, buf1, buf_size, 0) != buf_size) { 505 + perror("send failed"); 506 + exit(EXIT_FAILURE); 507 + } 508 + 509 + if (send(fd, buf2, buf_size, 0) != buf_size) { 510 + perror("send failed"); 511 + exit(EXIT_FAILURE); 512 + } 513 + 514 + close(fd); 515 + } 516 + 517 + static void test_seqpacket_invalid_rec_buffer_server(const struct test_opts *opts) 518 + { 519 + int fd; 520 + unsigned char *broken_buf; 521 + unsigned char *valid_buf; 522 + int page_size = getpagesize(); 523 + int buf_size = page_size * 3; 524 + ssize_t res; 525 + int prot = PROT_READ | PROT_WRITE; 526 + int flags = MAP_PRIVATE | MAP_ANONYMOUS; 527 + int i; 528 + 529 + fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL); 530 + if (fd < 0) { 531 + perror("accept"); 532 + exit(EXIT_FAILURE); 533 + } 534 + 535 + /* Setup first buffer. */ 536 + broken_buf = mmap(NULL, buf_size, prot, flags, -1, 0); 537 + if (broken_buf == MAP_FAILED) { 538 + perror("mmap for 'broken_buf'"); 539 + exit(EXIT_FAILURE); 540 + } 541 + 542 + /* Unmap "hole" in buffer. */ 543 + if (munmap(broken_buf + page_size, page_size)) { 544 + perror("'broken_buf' setup"); 545 + exit(EXIT_FAILURE); 546 + } 547 + 548 + valid_buf = mmap(NULL, buf_size, prot, flags, -1, 0); 549 + if (valid_buf == MAP_FAILED) { 550 + perror("mmap for 'valid_buf'"); 551 + exit(EXIT_FAILURE); 552 + } 553 + 554 + /* Try to fill buffer with unmapped middle. */ 555 + res = read(fd, broken_buf, buf_size); 556 + if (res != -1) { 557 + fprintf(stderr, 558 + "expected 'broken_buf' read(2) failure, got %zi\n", 559 + res); 560 + exit(EXIT_FAILURE); 561 + } 562 + 563 + if (errno != ENOMEM) { 564 + perror("unexpected errno of 'broken_buf'"); 565 + exit(EXIT_FAILURE); 566 + } 567 + 568 + /* Try to fill valid buffer. */ 569 + res = read(fd, valid_buf, buf_size); 570 + if (res < 0) { 571 + perror("unexpected 'valid_buf' read(2) failure"); 572 + exit(EXIT_FAILURE); 573 + } 574 + 575 + if (res != buf_size) { 576 + fprintf(stderr, 577 + "invalid 'valid_buf' read(2), expected %i, got %zi\n", 578 + buf_size, res); 579 + exit(EXIT_FAILURE); 580 + } 581 + 582 + for (i = 0; i < buf_size; i++) { 583 + if (valid_buf[i] != BUF_PATTERN_2) { 584 + fprintf(stderr, 585 + "invalid pattern for 'valid_buf' at %i, expected %hhX, got %hhX\n", 586 + i, BUF_PATTERN_2, valid_buf[i]); 587 + exit(EXIT_FAILURE); 588 + } 589 + } 590 + 591 + /* Unmap buffers. */ 592 + munmap(broken_buf, page_size); 593 + munmap(broken_buf + page_size * 2, page_size); 594 + munmap(valid_buf, buf_size); 595 + close(fd); 596 + } 597 + 474 598 static struct test_case test_cases[] = { 475 599 { 476 600 .name = "SOCK_STREAM connection reset", ··· 640 514 .name = "SOCK_SEQPACKET timeout", 641 515 .run_client = test_seqpacket_timeout_client, 642 516 .run_server = test_seqpacket_timeout_server, 517 + }, 518 + { 519 + .name = "SOCK_SEQPACKET invalid receive buffer", 520 + .run_client = test_seqpacket_invalid_rec_buffer_client, 521 + .run_server = test_seqpacket_invalid_rec_buffer_server, 643 522 }, 644 523 {}, 645 524 };