diff options
author | schwarze <> | 2022-12-07 23:08:47 +0000 |
---|---|---|
committer | schwarze <> | 2022-12-07 23:08:47 +0000 |
commit | 2b85b069ff24153ddd491689b70f49f463f7ec09 (patch) | |
tree | 7178fce139a8fda53f64f545e4defa1639910a6e /src/lib | |
parent | 73183671d4b543adc49a79ea1adaa69bcb91c859 (diff) | |
download | openbsd-2b85b069ff24153ddd491689b70f49f463f7ec09.tar.gz openbsd-2b85b069ff24153ddd491689b70f49f463f7ec09.tar.bz2 openbsd-2b85b069ff24153ddd491689b70f49f463f7ec09.zip |
Improve the implementation of BIO_push(3) such that it changes nothing
and reports failure if a call would result in a cycle.
The algorithm used was originally suggested by jsing@.
Feedback and OK tb@.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/bio/bio_lib.c | 8 | ||||
-rw-r--r-- | src/lib/libcrypto/man/BIO_push.3 | 37 |
2 files changed, 39 insertions, 6 deletions
diff --git a/src/lib/libcrypto/bio/bio_lib.c b/src/lib/libcrypto/bio/bio_lib.c index 4c3d7ed5f5..3eb0869ca9 100644 --- a/src/lib/libcrypto/bio/bio_lib.c +++ b/src/lib/libcrypto/bio/bio_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio_lib.c,v 1.41 2022/12/06 17:59:21 schwarze Exp $ */ | 1 | /* $OpenBSD: bio_lib.c,v 1.42 2022/12/07 23:08:47 schwarze Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -637,6 +637,12 @@ BIO_push(BIO *b, BIO *bio) | |||
637 | 637 | ||
638 | if (b == NULL) | 638 | if (b == NULL) |
639 | return (bio); | 639 | return (bio); |
640 | |||
641 | /* If this would create a cycle, change nothing and fail. */ | ||
642 | for (lb = bio; lb != NULL; lb = lb->next_bio) | ||
643 | if (lb == b) | ||
644 | return NULL; | ||
645 | |||
640 | lb = b; | 646 | lb = b; |
641 | while (lb->next_bio != NULL) | 647 | while (lb->next_bio != NULL) |
642 | lb = lb->next_bio; | 648 | lb = lb->next_bio; |
diff --git a/src/lib/libcrypto/man/BIO_push.3 b/src/lib/libcrypto/man/BIO_push.3 index d091c7ccca..01f426c1ef 100644 --- a/src/lib/libcrypto/man/BIO_push.3 +++ b/src/lib/libcrypto/man/BIO_push.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: BIO_push.3,v 1.10 2022/12/07 22:30:15 tb Exp $ | 1 | .\" $OpenBSD: BIO_push.3,v 1.11 2022/12/07 23:08:47 schwarze Exp $ |
2 | .\" full merge up to: | 2 | .\" full merge up to: |
3 | .\" OpenSSL doc/man3/BIO_push.pod 791bfd91 Nov 19 20:38:27 2021 +0100 | 3 | .\" OpenSSL doc/man3/BIO_push.pod 791bfd91 Nov 19 20:38:27 2021 +0100 |
4 | .\" OpenSSL doc/man7/bio.pod 1cb7eff4 Sep 10 13:56:40 2019 +0100 | 4 | .\" OpenSSL doc/man7/bio.pod 1cb7eff4 Sep 10 13:56:40 2019 +0100 |
@@ -105,6 +105,7 @@ It is either at the end of its chain | |||
105 | or there is exactly one following BIO. | 105 | or there is exactly one following BIO. |
106 | If there is neither a preceding nor a following BIO, | 106 | If there is neither a preceding nor a following BIO, |
107 | it can be regarded as a chain with one member. | 107 | it can be regarded as a chain with one member. |
108 | Every chain has exactly one beginning and exactly one end. | ||
108 | .Pp | 109 | .Pp |
109 | .Fn BIO_push | 110 | .Fn BIO_push |
110 | appends the chain starting at | 111 | appends the chain starting at |
@@ -140,6 +141,11 @@ For portability, it is best to make sure that | |||
140 | is at the beginning of its chain before calling | 141 | is at the beginning of its chain before calling |
141 | .Fn BIO_push . | 142 | .Fn BIO_push . |
142 | .Pp | 143 | .Pp |
144 | The LibreSSL implementation of | ||
145 | .Fn BIO_push | ||
146 | never creates cycles. | ||
147 | If a call would result in a cycle, nothing is changed and the call fails. | ||
148 | .Pp | ||
143 | .Fn BIO_pop | 149 | .Fn BIO_pop |
144 | removes the BIO | 150 | removes the BIO |
145 | .Fa b | 151 | .Fa b |
@@ -208,11 +214,16 @@ have any effect is | |||
208 | .Fn BIO_push | 214 | .Fn BIO_push |
209 | returns | 215 | returns |
210 | .Fa b | 216 | .Fa b |
211 | if it is not | 217 | for success or a different pointer for failure. |
212 | .Dv NULL | 218 | In particular, it fails and returns |
213 | or | ||
214 | .Fa new_tail | 219 | .Fa new_tail |
215 | if it is. | 220 | if |
221 | .Fa b | ||
222 | is | ||
223 | .Dv NULL . | ||
224 | In LibreSSL, it fails and returns | ||
225 | .Dv NULL | ||
226 | if appending would create a cycle. | ||
216 | .Pp | 227 | .Pp |
217 | .Fn BIO_pop | 228 | .Fn BIO_pop |
218 | returns the BIO that followed | 229 | returns the BIO that followed |
@@ -283,6 +294,22 @@ and the new chain will be | |||
283 | data can be written to | 294 | data can be written to |
284 | .Sy md1 | 295 | .Sy md1 |
285 | as before. | 296 | as before. |
297 | .Pp | ||
298 | Even though LibreSSL handles some of the edge cases gracefully, | ||
299 | the following idiom is recommended for portable error checking: | ||
300 | .Bd -literal -offset indent | ||
301 | if (b == NULL || new_tail == NULL || b == new_tail) | ||
302 | /* Report the problem and bail out. */ | ||
303 | if (BIO_push(b, new_tail) != b) | ||
304 | /* Report that nothing was changed | ||
305 | * because it would have created a cycle. */ | ||
306 | .Ed | ||
307 | .Pp | ||
308 | Even with the portable idiom, old and non-LibreSSL library implementations | ||
309 | may silently attempt to create cycles instead of rejecting them and returning | ||
310 | .Dv NULL , | ||
311 | which may result in infinite loops, infinite recursion, or segmentation | ||
312 | faults either right away or later on. | ||
286 | .Sh SEE ALSO | 313 | .Sh SEE ALSO |
287 | .Xr BIO_find_type 3 , | 314 | .Xr BIO_find_type 3 , |
288 | .Xr BIO_new 3 , | 315 | .Xr BIO_new 3 , |