diff options
Diffstat (limited to '')
-rw-r--r-- | src/regress/lib/libcrypto/bio/bio_chain.c | 148 |
1 files changed, 89 insertions, 59 deletions
diff --git a/src/regress/lib/libcrypto/bio/bio_chain.c b/src/regress/lib/libcrypto/bio/bio_chain.c index 1676a5f512..3453312e06 100644 --- a/src/regress/lib/libcrypto/bio/bio_chain.c +++ b/src/regress/lib/libcrypto/bio/bio_chain.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio_chain.c,v 1.3 2022/12/08 18:12:39 tb Exp $ */ | 1 | /* $OpenBSD: bio_chain.c,v 1.4 2022/12/08 18:15:36 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> | 3 | * Copyright (c) 2022 Theo Buehler <tb@openbsd.org> |
4 | * | 4 | * |
@@ -23,7 +23,13 @@ | |||
23 | 23 | ||
24 | #include "bio_local.h" | 24 | #include "bio_local.h" |
25 | 25 | ||
26 | #define N_CHAIN_BIOS 5 | 26 | #ifndef nitems |
27 | #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) | ||
28 | #endif | ||
29 | |||
30 | #define CHAIN_POP_LEN 5 | ||
31 | #define LINK_CHAIN_A_LEN 8 | ||
32 | #define LINK_CHAIN_B_LEN 5 | ||
27 | 33 | ||
28 | static BIO * | 34 | static BIO * |
29 | BIO_prev(BIO *bio) | 35 | BIO_prev(BIO *bio) |
@@ -34,25 +40,61 @@ BIO_prev(BIO *bio) | |||
34 | return bio->prev_bio; | 40 | return bio->prev_bio; |
35 | } | 41 | } |
36 | 42 | ||
43 | static void bio_chain_destroy(BIO **, size_t); | ||
44 | |||
45 | static int | ||
46 | bio_chain_create(const BIO_METHOD *meth, BIO *chain[], size_t len) | ||
47 | { | ||
48 | BIO *prev; | ||
49 | size_t i; | ||
50 | |||
51 | memset(chain, 0, len * sizeof(BIO *)); | ||
52 | |||
53 | prev = NULL; | ||
54 | for (i = 0; i < len; i++) { | ||
55 | if ((chain[i] = BIO_new(meth)) == NULL) { | ||
56 | fprintf(stderr, "BIO_new failed\n"); | ||
57 | goto err; | ||
58 | } | ||
59 | if ((prev = BIO_push(prev, chain[i])) == NULL) { | ||
60 | fprintf(stderr, "BIO_push failed\n"); | ||
61 | goto err; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | return 1; | ||
66 | |||
67 | err: | ||
68 | bio_chain_destroy(chain, len); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | bio_chain_destroy(BIO *chain[], size_t len) | ||
75 | { | ||
76 | size_t i; | ||
77 | |||
78 | for (i = 0; i < len; i++) | ||
79 | BIO_free(chain[i]); | ||
80 | |||
81 | memset(chain, 0, len * sizeof(BIO *)); | ||
82 | } | ||
83 | |||
37 | static int | 84 | static int |
38 | bio_chain_pop_test(void) | 85 | bio_chain_pop_test(void) |
39 | { | 86 | { |
40 | BIO *bio[N_CHAIN_BIOS]; | 87 | BIO *bio[CHAIN_POP_LEN]; |
41 | BIO *prev, *next; | 88 | BIO *prev, *next; |
42 | size_t i, j; | 89 | size_t i, j; |
43 | int failed = 1; | 90 | int failed = 1; |
44 | 91 | ||
45 | for (i = 0; i < N_CHAIN_BIOS; i++) { | 92 | for (i = 0; i < nitems(bio); i++) { |
46 | memset(bio, 0, sizeof(bio)); | 93 | memset(bio, 0, sizeof(bio)); |
47 | prev = NULL; | 94 | prev = NULL; |
48 | 95 | ||
49 | /* Create a linear chain of BIOs. */ | 96 | if (!bio_chain_create(BIO_s_null(), bio, nitems(bio))) |
50 | for (j = 0; j < N_CHAIN_BIOS; j++) { | 97 | goto err; |
51 | if ((bio[j] = BIO_new(BIO_s_null())) == NULL) | ||
52 | errx(1, "BIO_new"); | ||
53 | if ((prev = BIO_push(prev, bio[j])) == NULL) | ||
54 | errx(1, "BIO_push"); | ||
55 | } | ||
56 | 98 | ||
57 | /* Check that the doubly-linked list was set up as expected. */ | 99 | /* Check that the doubly-linked list was set up as expected. */ |
58 | if (BIO_prev(bio[0]) != NULL) { | 100 | if (BIO_prev(bio[0]) != NULL) { |
@@ -60,11 +102,11 @@ bio_chain_pop_test(void) | |||
60 | "i = %zu: first BIO has predecessor\n", i); | 102 | "i = %zu: first BIO has predecessor\n", i); |
61 | goto err; | 103 | goto err; |
62 | } | 104 | } |
63 | if (BIO_next(bio[N_CHAIN_BIOS - 1]) != NULL) { | 105 | if (BIO_next(bio[nitems(bio) - 1]) != NULL) { |
64 | fprintf(stderr, "i = %zu: last BIO has successor\n", i); | 106 | fprintf(stderr, "i = %zu: last BIO has successor\n", i); |
65 | goto err; | 107 | goto err; |
66 | } | 108 | } |
67 | for (j = 0; j < N_CHAIN_BIOS; j++) { | 109 | for (j = 0; j < nitems(bio); j++) { |
68 | if (j > 0) { | 110 | if (j > 0) { |
69 | if (BIO_prev(bio[j]) != bio[j - 1]) { | 111 | if (BIO_prev(bio[j]) != bio[j - 1]) { |
70 | fprintf(stderr, "i = %zu: " | 112 | fprintf(stderr, "i = %zu: " |
@@ -73,7 +115,7 @@ bio_chain_pop_test(void) | |||
73 | goto err; | 115 | goto err; |
74 | } | 116 | } |
75 | } | 117 | } |
76 | if (j < N_CHAIN_BIOS - 1) { | 118 | if (j < nitems(bio) - 1) { |
77 | if (BIO_next(bio[j]) != bio[j + 1]) { | 119 | if (BIO_next(bio[j]) != bio[j + 1]) { |
78 | fprintf(stderr, "i = %zu: " | 120 | fprintf(stderr, "i = %zu: " |
79 | "BIO_next(bio[%zu]) != bio[%zu]\n", | 121 | "BIO_next(bio[%zu]) != bio[%zu]\n", |
@@ -92,7 +134,7 @@ bio_chain_pop_test(void) | |||
92 | goto err; | 134 | goto err; |
93 | } | 135 | } |
94 | 136 | ||
95 | if (i < N_CHAIN_BIOS - 1) { | 137 | if (i < nitems(bio) - 1) { |
96 | if (next != bio[i + 1]) { | 138 | if (next != bio[i + 1]) { |
97 | fprintf(stderr, "BIO_pop(bio[%zu]) did not " | 139 | fprintf(stderr, "BIO_pop(bio[%zu]) did not " |
98 | "return bio[%zu]\n", i, i + 1); | 140 | "return bio[%zu]\n", i, i + 1); |
@@ -118,7 +160,7 @@ bio_chain_pop_test(void) | |||
118 | j = 1; | 160 | j = 1; |
119 | } | 161 | } |
120 | 162 | ||
121 | for (; j < N_CHAIN_BIOS; j++) { | 163 | for (; j < nitems(bio); j++) { |
122 | if (j == i) | 164 | if (j == i) |
123 | continue; | 165 | continue; |
124 | if (BIO_next(prev) != bio[j]) { | 166 | if (BIO_next(prev) != bio[j]) { |
@@ -139,16 +181,13 @@ bio_chain_pop_test(void) | |||
139 | goto err; | 181 | goto err; |
140 | } | 182 | } |
141 | 183 | ||
142 | for (j = 0; j < N_CHAIN_BIOS; j++) | 184 | bio_chain_destroy(bio, nitems(bio)); |
143 | BIO_free(bio[j]); | ||
144 | memset(bio, 0, sizeof(bio)); | ||
145 | } | 185 | } |
146 | 186 | ||
147 | failed = 0; | 187 | failed = 0; |
148 | 188 | ||
149 | err: | 189 | err: |
150 | for (i = 0; i < N_CHAIN_BIOS; i++) | 190 | bio_chain_destroy(bio, nitems(bio)); |
151 | BIO_free(bio[i]); | ||
152 | 191 | ||
153 | return failed; | 192 | return failed; |
154 | } | 193 | } |
@@ -245,26 +284,26 @@ check_chain(BIO *start, BIO *end, size_t expected_length, | |||
245 | } | 284 | } |
246 | 285 | ||
247 | /* | 286 | /* |
248 | * Link two linear chains of BIOs, A[] and B[], of length N_CHAIN_BIOS together | 287 | * Link two linear chains of BIOs A[] and B[] together using either |
249 | * using either BIO_push(A[i], B[j]) or BIO_set_next(A[i], B[j]). | 288 | * BIO_push(A[i], B[j]) or BIO_set_next(A[i], B[j]). |
250 | * | 289 | * |
251 | * BIO_push() first walks the chain A[] to its end and then appends the tail | 290 | * BIO_push() first walks the chain A[] to its end and then appends the tail |
252 | * of chain B[] starting at B[j]. If j > 0, we get two chains | 291 | * of chain B[] starting at B[j]. If j > 0, we get two chains |
253 | * | 292 | * |
254 | * A[0] -- ... -- A[N_CHAIN_BIOS - 1] -- B[j] -- ... -- B[N_CHAIN_BIOS - 1] | 293 | * A[0] -- ... -- A[nitems(A) - 1] -- B[j] -- ... -- B[nitems(B) - 1] |
255 | * `- link created by BIO_push() | 294 | * `- link created by BIO_push() |
256 | * B[0] -- ... -- B[j-1] | 295 | * B[0] -- ... -- B[j-1] |
257 | * |<-- oldhead -->| | 296 | * |<-- oldhead -->| |
258 | * | 297 | * |
259 | * of lengths N_CHAIN_BIOS + N_CHAIN_BIOS - j and j, respectively. | 298 | * of lengths nitems(A) + nitems(B) - j and j, respectively. |
260 | * If j == 0, the second chain (oldhead) is empty. One quirk of BIO_push() is | 299 | * If j == 0, the second chain (oldhead) is empty. One quirk of BIO_push() is |
261 | * that the outcome of BIO_push(A[i], B[j]) apart from the return value is | 300 | * that the outcome of BIO_push(A[i], B[j]) apart from the return value is |
262 | * independent of i. | 301 | * independent of i. |
263 | * | 302 | * |
264 | * Prior to bio_lib.c r1.41, BIO_push(A[i], B[j]) would fail to dissociate the | 303 | * Prior to bio_lib.c r1.41, BIO_push(A[i], B[j]) would fail to dissociate the |
265 | * two chains and leave B[j] with two parents for 0 < j < N_CHAIN_BIOS. | 304 | * two chains and leave B[j] with two parents for 0 < j < nitems(B). |
266 | * B[j]->prev_bio would point at A[N_CHAIN_BIOS - 1], while both B[j - 1] and | 305 | * B[j]->prev_bio would point at A[nitems(A) - 1], while both B[j - 1] and |
267 | * A[N_CHAIN_BIOS - 1] would point at B[j]. In particular, BIO_free_all(A[0]) | 306 | * A[nitems(A) - 1] would point at B[j]. In particular, BIO_free_all(A[0]) |
268 | * followed by BIO_free_all(B[0]) results in a double free of B[j]. | 307 | * followed by BIO_free_all(B[0]) results in a double free of B[j]. |
269 | * | 308 | * |
270 | * The result for BIO_set_next() is different: three chains are created. | 309 | * The result for BIO_set_next() is different: three chains are created. |
@@ -276,8 +315,8 @@ check_chain(BIO *start, BIO *end, size_t expected_length, | |||
276 | * --- oldhead -->| \ | 315 | * --- oldhead -->| \ |
277 | * ... -- B[j-1] -- B[j] -- B[j+1] -- ... | 316 | * ... -- B[j-1] -- B[j] -- B[j+1] -- ... |
278 | * | 317 | * |
279 | * After creating a new link, the new chain has length i + 1 + N_CHAIN_BIOS - j, | 318 | * After creating a new link, the new chain has length i + 1 + nitems(B) - j, |
280 | * oldtail has length N_CHAIN_BIOS - i - 1 and oldhead has length j. | 319 | * oldtail has length nitems(A) - i - 1 and oldhead has length j. |
281 | * | 320 | * |
282 | * Prior to bio_lib.c r1.40, BIO_set_next(A[i], B[j]) results in both A[i] and | 321 | * Prior to bio_lib.c r1.40, BIO_set_next(A[i], B[j]) results in both A[i] and |
283 | * B[j - 1] pointing at B[j] while B[j] points back at A[i]. The result is | 322 | * B[j - 1] pointing at B[j] while B[j] points back at A[i]. The result is |
@@ -290,37 +329,30 @@ static int | |||
290 | link_chains_at(size_t i, size_t j, int use_bio_push) | 329 | link_chains_at(size_t i, size_t j, int use_bio_push) |
291 | { | 330 | { |
292 | const char *fn = use_bio_push ? "BIO_push" : "BIO_set_next"; | 331 | const char *fn = use_bio_push ? "BIO_push" : "BIO_set_next"; |
293 | BIO *A[N_CHAIN_BIOS], *B[N_CHAIN_BIOS]; | 332 | BIO *A[LINK_CHAIN_A_LEN], *B[LINK_CHAIN_B_LEN]; |
294 | BIO *new_start, *new_end, *prev; | 333 | BIO *new_start, *new_end; |
295 | BIO *oldhead_start, *oldhead_end, *oldtail_start, *oldtail_end; | 334 | BIO *oldhead_start, *oldhead_end, *oldtail_start, *oldtail_end; |
296 | size_t k, new_length, oldhead_length, oldtail_length; | 335 | size_t new_length, oldhead_length, oldtail_length; |
297 | int failed = 1; | 336 | int failed = 1; |
298 | 337 | ||
299 | memset(A, 0, sizeof(A)); | 338 | memset(A, 0, sizeof(A)); |
300 | memset(B, 0, sizeof(B)); | 339 | memset(B, 0, sizeof(B)); |
301 | 340 | ||
341 | if (i > nitems(A) || j > nitems(B)) | ||
342 | goto err; | ||
343 | |||
302 | /* Create two linear chains of BIOs. */ | 344 | /* Create two linear chains of BIOs. */ |
303 | prev = NULL; | 345 | if (!bio_chain_create(BIO_s_null(), A, nitems(A))) |
304 | for (k = 0; k < N_CHAIN_BIOS; k++) { | 346 | goto err; |
305 | if ((A[k] = BIO_new(BIO_s_null())) == NULL) | 347 | if (!bio_chain_create(BIO_s_null(), B, nitems(B))) |
306 | errx(1, "BIO_new"); | 348 | goto err; |
307 | if ((prev = BIO_push(prev, A[k])) == NULL) | ||
308 | errx(1, "BIO_push"); | ||
309 | } | ||
310 | prev = NULL; | ||
311 | for (k = 0; k < N_CHAIN_BIOS; k++) { | ||
312 | if ((B[k] = BIO_new(BIO_s_null())) == NULL) | ||
313 | errx(1, "BIO_new"); | ||
314 | if ((prev = BIO_push(prev, B[k])) == NULL) | ||
315 | errx(1, "BIO_push"); | ||
316 | } | ||
317 | 349 | ||
318 | /* | 350 | /* |
319 | * Set our expectations. ... it's complicated. | 351 | * Set our expectations. ... it's complicated. |
320 | */ | 352 | */ |
321 | 353 | ||
322 | new_start = A[0]; | 354 | new_start = A[0]; |
323 | new_end = B[N_CHAIN_BIOS - 1]; | 355 | new_end = B[nitems(B) - 1]; |
324 | 356 | ||
325 | oldhead_length = j; | 357 | oldhead_length = j; |
326 | oldhead_start = B[0]; | 358 | oldhead_start = B[0]; |
@@ -333,18 +365,18 @@ link_chains_at(size_t i, size_t j, int use_bio_push) | |||
333 | } | 365 | } |
334 | 366 | ||
335 | if (use_bio_push) { | 367 | if (use_bio_push) { |
336 | new_length = N_CHAIN_BIOS + N_CHAIN_BIOS - j; | 368 | new_length = nitems(A) + nitems(B) - j; |
337 | 369 | ||
338 | /* oldtail doesn't exist in the BIO_push() case. */ | 370 | /* oldtail doesn't exist in the BIO_push() case. */ |
339 | oldtail_start = NULL; | 371 | oldtail_start = NULL; |
340 | oldtail_end = NULL; | 372 | oldtail_end = NULL; |
341 | oldtail_length = 0; | 373 | oldtail_length = 0; |
342 | } else { | 374 | } else { |
343 | new_length = i + 1 + N_CHAIN_BIOS - j; | 375 | new_length = i + 1 + nitems(B) - j; |
344 | 376 | ||
345 | oldtail_start = BIO_next(A[i]); | 377 | oldtail_start = BIO_next(A[i]); |
346 | oldtail_end = A[N_CHAIN_BIOS - 1]; | 378 | oldtail_end = A[nitems(A) - 1]; |
347 | oldtail_length = N_CHAIN_BIOS - i - 1; | 379 | oldtail_length = nitems(A) - i - 1; |
348 | } | 380 | } |
349 | 381 | ||
350 | /* | 382 | /* |
@@ -391,10 +423,8 @@ link_chains_at(size_t i, size_t j, int use_bio_push) | |||
391 | failed = 0; | 423 | failed = 0; |
392 | 424 | ||
393 | err: | 425 | err: |
394 | for (i = 0; i < N_CHAIN_BIOS; i++) | 426 | bio_chain_destroy(A, nitems(A)); |
395 | BIO_free(A[i]); | 427 | bio_chain_destroy(B, nitems(B)); |
396 | for (i = 0; i < N_CHAIN_BIOS; i++) | ||
397 | BIO_free(B[i]); | ||
398 | 428 | ||
399 | return failed; | 429 | return failed; |
400 | } | 430 | } |
@@ -405,8 +435,8 @@ link_chains(int use_bio_push) | |||
405 | size_t i, j; | 435 | size_t i, j; |
406 | int failure = 0; | 436 | int failure = 0; |
407 | 437 | ||
408 | for (i = 0; i < N_CHAIN_BIOS; i++) { | 438 | for (i = 0; i < LINK_CHAIN_A_LEN; i++) { |
409 | for (j = 0; j < N_CHAIN_BIOS; j++) { | 439 | for (j = 0; j < LINK_CHAIN_B_LEN; j++) { |
410 | failure |= link_chains_at(i, j, use_bio_push); | 440 | failure |= link_chains_at(i, j, use_bio_push); |
411 | } | 441 | } |
412 | } | 442 | } |