diff options
| author | tb <> | 2022-12-08 11:32:27 +0000 |
|---|---|---|
| committer | tb <> | 2022-12-08 11:32:27 +0000 |
| commit | fcac0017bcd7a37bcb9dfd7c35dbf36dff59d64e (patch) | |
| tree | 58d4aa14aa923d5ff191e620552ac1b31e29c190 /src/regress/lib/libc | |
| parent | 2a9849a4fa03ac30a7766bfc597d055a16a07e83 (diff) | |
| download | openbsd-fcac0017bcd7a37bcb9dfd7c35dbf36dff59d64e.tar.gz openbsd-fcac0017bcd7a37bcb9dfd7c35dbf36dff59d64e.tar.bz2 openbsd-fcac0017bcd7a37bcb9dfd7c35dbf36dff59d64e.zip | |
Add BIO_push() and BIO_set_next() regress coverage
This tests for the behavior changes in bio_lib.c r1.40 and r1.41 and
makes sure that BIO_push() and BIO_set_next() act on two chains in the
expected and now documented way.
Diffstat (limited to '')
| -rw-r--r-- | src/regress/lib/libcrypto/bio/biotest.c | 368 |
1 files changed, 367 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/bio/biotest.c b/src/regress/lib/libcrypto/bio/biotest.c index 55daea78fc..7d56448bfa 100644 --- a/src/regress/lib/libcrypto/bio/biotest.c +++ b/src/regress/lib/libcrypto/bio/biotest.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: biotest.c,v 1.10 2022/12/03 09:53:47 tb Exp $ */ | 1 | /* $OpenBSD: biotest.c,v 1.11 2022/12/08 11:32:27 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2014, 2022 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014, 2022 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> | 4 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> |
| @@ -598,6 +598,370 @@ do_bio_chain_pop_test(void) | |||
| 598 | return failed; | 598 | return failed; |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | /* | ||
| 602 | * Link two linear chains of BIOs, A[], B[] of length N_CHAIN_BIOS together | ||
| 603 | * using either BIO_push(A[i], B[j]) or BIO_set_next(A[i], B[j]). | ||
| 604 | * | ||
| 605 | * BIO_push() first walks the chain A[] to its end and then appends the tail | ||
| 606 | * of chain B[] starting at B[j]. If j > 0, we get two chains | ||
| 607 | * | ||
| 608 | * A[0] -- ... -- A[N_CHAIN_BIOS - 1] -- B[j] -- ... -- B[N_CHAIN_BIOS - 1] | ||
| 609 | * | ||
| 610 | * B[0] -- ... -- B[j-1] | ||
| 611 | * --- oldhead -->| | ||
| 612 | * | ||
| 613 | * of lengths N_CHAIN_BIOS + N_CHAIN_BIOS - j and j, respectively. | ||
| 614 | * If j == 0, the second chain (oldhead) is empty. One quirk of BIO_push() is | ||
| 615 | * that the outcome of BIO_push(A[i], B[j]) apart from the return value is | ||
| 616 | * independent of i. | ||
| 617 | * | ||
| 618 | * Prior to bio_lib.c r1.41, BIO_push() would keep * BIO_next(B[j-1]) == B[j] | ||
| 619 | * for 0 < j < N_CHAIN_BIOS, and at the same time for all j the inconsistent | ||
| 620 | * BIO_prev(B[j]) == A[N_CHAIN_BIOS - 1]. | ||
| 621 | * | ||
| 622 | * The result for BIO_set_next() is different: three chains are created. | ||
| 623 | * | ||
| 624 | * |--- oldtail --> | ||
| 625 | * ... -- A[i-1] -- A[i] -- A[i+1] -- ... | ||
| 626 | * \ | ||
| 627 | * \ new link created by BIO_set_next() | ||
| 628 | * --- oldhead -->| \ | ||
| 629 | * ... -- B[j-1] -- B[j] -- B[j+1] -- ... | ||
| 630 | * | ||
| 631 | * After creating a new link, the new chain has length i + 1 + N_CHAIN_BIOS - j, | ||
| 632 | * oldtail has length N_CHAIN_BIOS - i - 1 and oldhead has length j. | ||
| 633 | * | ||
| 634 | * Prior to bio_lib.c r1.40, BIO_set_next() results in BIO_next(B[j-1]) == B[j], | ||
| 635 | * B[j-1] == BIO_prev(B[j]), A[i] == BIO_prev(A[i+1]) and, in addition, | ||
| 636 | * BIO_next(A[i]) == B[j], thus leaving A[] and B[] in an inconsistent state. | ||
| 637 | * | ||
| 638 | * XXX: Should check that the callback is called on BIO_push() as expected. | ||
| 639 | */ | ||
| 640 | |||
| 641 | static int | ||
| 642 | do_bio_link_chains_at(size_t i, size_t j, int use_bio_push) | ||
| 643 | { | ||
| 644 | BIO *A[N_CHAIN_BIOS], *B[N_CHAIN_BIOS]; | ||
| 645 | BIO *oldhead_start, *oldhead_end, *oldtail_start, *oldtail_end; | ||
| 646 | BIO *prev, *next; | ||
| 647 | size_t k, length, new_chain_length, oldhead_length, oldtail_length; | ||
| 648 | int failed = 1; | ||
| 649 | |||
| 650 | memset(A, 0, sizeof(A)); | ||
| 651 | memset(B, 0, sizeof(A)); | ||
| 652 | |||
| 653 | /* Create two linear chains of BIOs. */ | ||
| 654 | prev = NULL; | ||
| 655 | for (k = 0; k < N_CHAIN_BIOS; k++) { | ||
| 656 | if ((A[k] = BIO_new(BIO_s_null())) == NULL) | ||
| 657 | errx(1, "BIO_new"); | ||
| 658 | if ((prev = BIO_push(prev, A[k])) == NULL) | ||
| 659 | errx(1, "BIO_push"); | ||
| 660 | } | ||
| 661 | prev = NULL; | ||
| 662 | for (k = 0; k < N_CHAIN_BIOS; k++) { | ||
| 663 | if ((B[k] = BIO_new(BIO_s_null())) == NULL) | ||
| 664 | errx(1, "BIO_new"); | ||
| 665 | if ((prev = BIO_push(prev, B[k])) == NULL) | ||
| 666 | errx(1, "BIO_push"); | ||
| 667 | } | ||
| 668 | |||
| 669 | /* | ||
| 670 | * Set our expectations. ... it's complicated. | ||
| 671 | */ | ||
| 672 | |||
| 673 | oldhead_length = j; | ||
| 674 | oldhead_start = B[0]; | ||
| 675 | oldhead_end = BIO_prev(B[j]); | ||
| 676 | |||
| 677 | /* | ||
| 678 | * Adjust for edge case where we push B[0] or set next to B[0]. | ||
| 679 | * The oldhead chain is then empty. | ||
| 680 | */ | ||
| 681 | |||
| 682 | if (j == 0) { | ||
| 683 | if (oldhead_end != NULL) { | ||
| 684 | fprintf(stderr, "%s: oldhead(B) not empty at start\n", | ||
| 685 | __func__); | ||
| 686 | goto err; | ||
| 687 | } | ||
| 688 | |||
| 689 | oldhead_length = 0; | ||
| 690 | oldhead_start = NULL; | ||
| 691 | } | ||
| 692 | |||
| 693 | if (use_bio_push) { | ||
| 694 | new_chain_length = N_CHAIN_BIOS + N_CHAIN_BIOS - j; | ||
| 695 | |||
| 696 | /* oldtail doesn't exist in the BIO_push() case. */ | ||
| 697 | oldtail_start = NULL; | ||
| 698 | oldtail_end = NULL; | ||
| 699 | oldtail_length = 0; | ||
| 700 | } else { | ||
| 701 | new_chain_length = i + 1 + N_CHAIN_BIOS - j; | ||
| 702 | |||
| 703 | oldtail_start = BIO_next(A[i]); | ||
| 704 | oldtail_end = A[N_CHAIN_BIOS - 1]; | ||
| 705 | oldtail_length = N_CHAIN_BIOS - i - 1; | ||
| 706 | |||
| 707 | /* | ||
| 708 | * In case we push onto (or set next at) the end of A[], | ||
| 709 | * the oldtail chain is empty. | ||
| 710 | */ | ||
| 711 | if (i == N_CHAIN_BIOS - 1) { | ||
| 712 | if (oldtail_start != NULL) { | ||
| 713 | fprintf(stderr, | ||
| 714 | "%s: oldtail(A) not empty at end\n", | ||
| 715 | __func__); | ||
| 716 | goto err; | ||
| 717 | } | ||
| 718 | |||
| 719 | oldtail_end = NULL; | ||
| 720 | oldtail_length = 0; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | /* | ||
| 725 | * Now actually push or set next. | ||
| 726 | */ | ||
| 727 | |||
| 728 | if (use_bio_push) { | ||
| 729 | if (BIO_push(A[i], B[j]) != A[i]) { | ||
| 730 | fprintf(stderr, | ||
| 731 | "%s: BIO_push(A[%zu], B[%zu]) != A[%zu]\n", | ||
| 732 | __func__, i, j, i); | ||
| 733 | goto err; | ||
| 734 | } | ||
| 735 | } else { | ||
| 736 | BIO_set_next(A[i], B[j]); | ||
| 737 | } | ||
| 738 | |||
| 739 | /* | ||
| 740 | * Walk the new chain starting at A[0] forward. Check that we reach | ||
| 741 | * B[N_CHAIN_BIOS - 1] and that the new chain's length is as expected. | ||
| 742 | */ | ||
| 743 | |||
| 744 | next = A[0]; | ||
| 745 | length = 0; | ||
| 746 | do { | ||
| 747 | prev = next; | ||
| 748 | next = BIO_next(prev); | ||
| 749 | length++; | ||
| 750 | } while (next != NULL); | ||
| 751 | |||
| 752 | if (prev != B[N_CHAIN_BIOS - 1]) { | ||
| 753 | fprintf(stderr, | ||
| 754 | "%s(%zu, %zu, %d): new chain doesn't end in end of B\n", | ||
| 755 | __func__, i, j, use_bio_push); | ||
| 756 | goto err; | ||
| 757 | } | ||
| 758 | |||
| 759 | if (length != new_chain_length) { | ||
| 760 | fprintf(stderr, "%s(%zu, %zu, %d) unexpected new chain length" | ||
| 761 | " (walking forward). want %zu, got %zu\n", | ||
| 762 | __func__, i, j, use_bio_push, new_chain_length, length); | ||
| 763 | goto err; | ||
| 764 | } | ||
| 765 | |||
| 766 | /* | ||
| 767 | * Walk the new chain ending in B[N_CHAIN_BIOS - 1] backward. | ||
| 768 | * Check that we reach A[0] and that its length is what we expect. | ||
| 769 | */ | ||
| 770 | |||
| 771 | prev = B[N_CHAIN_BIOS - 1]; | ||
| 772 | length = 0; | ||
| 773 | do { | ||
| 774 | next = prev; | ||
| 775 | prev = BIO_prev(next); | ||
| 776 | length++; | ||
| 777 | } while (prev != NULL); | ||
| 778 | |||
| 779 | if (next != A[0]) { | ||
| 780 | fprintf(stderr, | ||
| 781 | "%s(%zu, %zu, %d): new chain doesn't start at start of A\n", | ||
| 782 | __func__, i, j, use_bio_push); | ||
| 783 | goto err; | ||
| 784 | } | ||
| 785 | |||
| 786 | if (length != new_chain_length) { | ||
| 787 | fprintf(stderr, "%s(%zu, %zu, %d) unexpected new chain length" | ||
| 788 | " (walking backward). want %zu, got %zu\n", | ||
| 789 | __func__, i, j, use_bio_push, new_chain_length, length); | ||
| 790 | goto err; | ||
| 791 | } | ||
| 792 | |||
| 793 | if (oldhead_start != NULL) { | ||
| 794 | |||
| 795 | /* | ||
| 796 | * Walk the old head forward and check its length. | ||
| 797 | */ | ||
| 798 | |||
| 799 | next = oldhead_start; | ||
| 800 | length = 0; | ||
| 801 | do { | ||
| 802 | prev = next; | ||
| 803 | next = BIO_next(prev); | ||
| 804 | length++; | ||
| 805 | } while (next != NULL); | ||
| 806 | |||
| 807 | if (prev != oldhead_end) { | ||
| 808 | fprintf(stderr, | ||
| 809 | "%s(%zu, %zu, %d): unexpected old head end\n", | ||
| 810 | __func__, i, j, use_bio_push); | ||
| 811 | goto err; | ||
| 812 | } | ||
| 813 | |||
| 814 | if (length != oldhead_length) { | ||
| 815 | fprintf(stderr, | ||
| 816 | "%s(%zu, %zu, %d) unexpected old head length" | ||
| 817 | " (walking forward). want %zu, got %zu\n", | ||
| 818 | __func__, i, j, use_bio_push, | ||
| 819 | oldhead_length, length); | ||
| 820 | goto err; | ||
| 821 | } | ||
| 822 | |||
| 823 | /* | ||
| 824 | * Walk the old head backward and check its length. | ||
| 825 | */ | ||
| 826 | |||
| 827 | prev = oldhead_end; | ||
| 828 | length = 0; | ||
| 829 | do { | ||
| 830 | next = prev; | ||
| 831 | prev = BIO_prev(next); | ||
| 832 | length++; | ||
| 833 | } while (prev != NULL); | ||
| 834 | |||
| 835 | if (next != oldhead_start) { | ||
| 836 | fprintf(stderr, | ||
| 837 | "%s(%zu, %zu, %d): unexpected old head start\n", | ||
| 838 | __func__, i, j, use_bio_push); | ||
| 839 | goto err; | ||
| 840 | } | ||
| 841 | |||
| 842 | if (length != oldhead_length) { | ||
| 843 | fprintf(stderr, | ||
| 844 | "%s(%zu, %zu, %d) unexpected old head length" | ||
| 845 | " (walking backward). want %zu, got %zu\n", | ||
| 846 | __func__, i, j, use_bio_push, | ||
| 847 | oldhead_length, length); | ||
| 848 | goto err; | ||
| 849 | } | ||
| 850 | } | ||
| 851 | |||
| 852 | if (oldtail_start != NULL) { | ||
| 853 | |||
| 854 | /* | ||
| 855 | * Walk the old tail forward and check its length. | ||
| 856 | */ | ||
| 857 | |||
| 858 | next = oldtail_start; | ||
| 859 | length = 0; | ||
| 860 | do { | ||
| 861 | prev = next; | ||
| 862 | next = BIO_next(prev); | ||
| 863 | length++; | ||
| 864 | } while (next != NULL); | ||
| 865 | |||
| 866 | if (prev != oldtail_end) { | ||
| 867 | fprintf(stderr, | ||
| 868 | "%s(%zu, %zu, %d): unexpected old tail end\n", | ||
| 869 | __func__, i, j, use_bio_push); | ||
| 870 | goto err; | ||
| 871 | } | ||
| 872 | |||
| 873 | if (length != oldtail_length) { | ||
| 874 | fprintf(stderr, | ||
| 875 | "%s(%zu, %zu, %d) unexpected old tail length" | ||
| 876 | " (walking forward). want %zu, got %zu\n", | ||
| 877 | __func__, i, j, use_bio_push, | ||
| 878 | oldtail_length, length); | ||
| 879 | goto err; | ||
| 880 | } | ||
| 881 | |||
| 882 | /* | ||
| 883 | * Walk the old tail backward and check its length. | ||
| 884 | */ | ||
| 885 | |||
| 886 | prev = oldtail_end; | ||
| 887 | length = 0; | ||
| 888 | do { | ||
| 889 | next = prev; | ||
| 890 | prev = BIO_prev(next); | ||
| 891 | length++; | ||
| 892 | } while (prev != NULL); | ||
| 893 | |||
| 894 | if (next != oldtail_start) { | ||
| 895 | fprintf(stderr, | ||
| 896 | "%s(%zu, %zu, %d): unexpected old tail start\n", | ||
| 897 | __func__, i, j, use_bio_push); | ||
| 898 | goto err; | ||
| 899 | } | ||
| 900 | |||
| 901 | if (length != oldtail_length) { | ||
| 902 | fprintf(stderr, | ||
| 903 | "%s(%zu, %zu, %d) unexpected old tail length" | ||
| 904 | " (walking backward). want %zu, got %zu\n", | ||
| 905 | __func__, i, j, use_bio_push, | ||
| 906 | oldtail_length, length); | ||
| 907 | goto err; | ||
| 908 | } | ||
| 909 | } | ||
| 910 | |||
| 911 | /* | ||
| 912 | * All sanity checks passed. We can now free the our chains | ||
| 913 | * with the BIO API without risk of leaks or double frees. | ||
| 914 | */ | ||
| 915 | |||
| 916 | BIO_free_all(A[0]); | ||
| 917 | BIO_free_all(oldhead_start); | ||
| 918 | BIO_free_all(oldtail_start); | ||
| 919 | |||
| 920 | memset(A, 0, sizeof(A)); | ||
| 921 | memset(B, 0, sizeof(B)); | ||
| 922 | |||
| 923 | failed = 0; | ||
| 924 | |||
| 925 | err: | ||
| 926 | for (i = 0; i < N_CHAIN_BIOS; i++) | ||
| 927 | BIO_free(A[i]); | ||
| 928 | for (i = 0; i < N_CHAIN_BIOS; i++) | ||
| 929 | BIO_free(B[i]); | ||
| 930 | |||
| 931 | return failed; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int | ||
| 935 | do_bio_link_chains(int use_bio_push) | ||
| 936 | { | ||
| 937 | size_t i, j; | ||
| 938 | int failure = 0; | ||
| 939 | |||
| 940 | for (i = 0; i < N_CHAIN_BIOS; i++) { | ||
| 941 | for (j = 0; j < N_CHAIN_BIOS; j++) { | ||
| 942 | failure |= do_bio_link_chains_at(i, j, use_bio_push); | ||
| 943 | } | ||
| 944 | } | ||
| 945 | |||
| 946 | return failure; | ||
| 947 | } | ||
| 948 | |||
| 949 | static int | ||
| 950 | do_bio_push_link_test(void) | ||
| 951 | { | ||
| 952 | int use_bio_push = 1; | ||
| 953 | |||
| 954 | return do_bio_link_chains(use_bio_push); | ||
| 955 | } | ||
| 956 | |||
| 957 | static int | ||
| 958 | do_bio_set_next_link_test(void) | ||
| 959 | { | ||
| 960 | int use_bio_push = 0; | ||
| 961 | |||
| 962 | return do_bio_link_chains(use_bio_push); | ||
| 963 | } | ||
| 964 | |||
| 601 | int | 965 | int |
| 602 | main(int argc, char **argv) | 966 | main(int argc, char **argv) |
| 603 | { | 967 | { |
| @@ -607,6 +971,8 @@ main(int argc, char **argv) | |||
| 607 | ret |= do_bio_get_port_tests(); | 971 | ret |= do_bio_get_port_tests(); |
| 608 | ret |= do_bio_mem_tests(); | 972 | ret |= do_bio_mem_tests(); |
| 609 | ret |= do_bio_chain_pop_test(); | 973 | ret |= do_bio_chain_pop_test(); |
| 974 | ret |= do_bio_push_link_test(); | ||
| 975 | ret |= do_bio_set_next_link_test(); | ||
| 610 | 976 | ||
| 611 | return (ret); | 977 | return (ret); |
| 612 | } | 978 | } |
