diff options
author | bcook <> | 2016-05-20 15:46:21 +0000 |
---|---|---|
committer | bcook <> | 2016-05-20 15:46:21 +0000 |
commit | b5dc80d643159abfc8d135107f29e2a3e1ca1594 (patch) | |
tree | 8e67e16e659a365d0ed501c64a8bf087a683477f /src | |
parent | ed17f10029fcc0b0f46842899c7b671233039b90 (diff) | |
download | openbsd-b5dc80d643159abfc8d135107f29e2a3e1ca1594.tar.gz openbsd-b5dc80d643159abfc8d135107f29e2a3e1ca1594.tar.bz2 openbsd-b5dc80d643159abfc8d135107f29e2a3e1ca1594.zip |
Fix a short-read bug in the previous version of asn1_d2i_read_bio
The outer while() loop is missing, so we only read up to chunk_max bytes.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/asn1/a_d2i_fp.c | 54 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_d2i_fp.c | 54 |
2 files changed, 56 insertions, 52 deletions
diff --git a/src/lib/libcrypto/asn1/a_d2i_fp.c b/src/lib/libcrypto/asn1/a_d2i_fp.c index 96416540c4..c00b304c61 100644 --- a/src/lib/libcrypto/asn1/a_d2i_fp.c +++ b/src/lib/libcrypto/asn1/a_d2i_fp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_d2i_fp.c,v 1.14 2016/05/04 14:58:09 tedu Exp $ */ | 1 | /* $OpenBSD: a_d2i_fp.c,v 1.15 2016/05/20 15:46:21 bcook 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 | * |
@@ -236,36 +236,38 @@ asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) | |||
236 | ASN1_R_TOO_LONG); | 236 | ASN1_R_TOO_LONG); |
237 | goto err; | 237 | goto err; |
238 | } | 238 | } |
239 | /* | 239 | while (want > 0) { |
240 | * Read content in chunks of increasing size | 240 | /* |
241 | * so we can return an error for EOF without | 241 | * Read content in chunks of increasing size |
242 | * having to allocate the entire content length | 242 | * so we can return an error for EOF without |
243 | * in one go. | 243 | * having to allocate the entire content length |
244 | */ | 244 | * in one go. |
245 | size_t chunk = want > chunk_max ? chunk_max : want; | 245 | */ |
246 | size_t chunk = want > chunk_max ? chunk_max : want; | ||
246 | 247 | ||
247 | if (!BUF_MEM_grow_clean(b, len + chunk)) { | 248 | if (!BUF_MEM_grow_clean(b, len + chunk)) { |
248 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, | ||
249 | ERR_R_MALLOC_FAILURE); | ||
250 | goto err; | ||
251 | } | ||
252 | want -= chunk; | ||
253 | while (chunk > 0) { | ||
254 | i = BIO_read(in, &(b->data[len]), chunk); | ||
255 | if (i <= 0) { | ||
256 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, | 249 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, |
257 | ASN1_R_NOT_ENOUGH_DATA); | 250 | ERR_R_MALLOC_FAILURE); |
258 | goto err; | 251 | goto err; |
259 | } | 252 | } |
260 | /* | 253 | want -= chunk; |
261 | * This can't overflow because |len+want| | 254 | while (chunk > 0) { |
262 | * didn't overflow. | 255 | i = BIO_read(in, &(b->data[len]), chunk); |
263 | */ | 256 | if (i <= 0) { |
264 | len += i; | 257 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, |
265 | chunk -= i; | 258 | ASN1_R_NOT_ENOUGH_DATA); |
259 | goto err; | ||
260 | } | ||
261 | /* | ||
262 | * This can't overflow because |len+want| | ||
263 | * didn't overflow. | ||
264 | */ | ||
265 | len += i; | ||
266 | chunk -= i; | ||
267 | } | ||
268 | if (chunk_max < INT_MAX/2) | ||
269 | chunk_max *= 2; | ||
266 | } | 270 | } |
267 | if (chunk_max < INT_MAX/2) | ||
268 | chunk_max *= 2; | ||
269 | } | 271 | } |
270 | if (off + c.slen < off) { | 272 | if (off + c.slen < off) { |
271 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); | 273 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); |
diff --git a/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c b/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c index 96416540c4..c00b304c61 100644 --- a/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c +++ b/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_d2i_fp.c,v 1.14 2016/05/04 14:58:09 tedu Exp $ */ | 1 | /* $OpenBSD: a_d2i_fp.c,v 1.15 2016/05/20 15:46:21 bcook 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 | * |
@@ -236,36 +236,38 @@ asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) | |||
236 | ASN1_R_TOO_LONG); | 236 | ASN1_R_TOO_LONG); |
237 | goto err; | 237 | goto err; |
238 | } | 238 | } |
239 | /* | 239 | while (want > 0) { |
240 | * Read content in chunks of increasing size | 240 | /* |
241 | * so we can return an error for EOF without | 241 | * Read content in chunks of increasing size |
242 | * having to allocate the entire content length | 242 | * so we can return an error for EOF without |
243 | * in one go. | 243 | * having to allocate the entire content length |
244 | */ | 244 | * in one go. |
245 | size_t chunk = want > chunk_max ? chunk_max : want; | 245 | */ |
246 | size_t chunk = want > chunk_max ? chunk_max : want; | ||
246 | 247 | ||
247 | if (!BUF_MEM_grow_clean(b, len + chunk)) { | 248 | if (!BUF_MEM_grow_clean(b, len + chunk)) { |
248 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, | ||
249 | ERR_R_MALLOC_FAILURE); | ||
250 | goto err; | ||
251 | } | ||
252 | want -= chunk; | ||
253 | while (chunk > 0) { | ||
254 | i = BIO_read(in, &(b->data[len]), chunk); | ||
255 | if (i <= 0) { | ||
256 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, | 249 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, |
257 | ASN1_R_NOT_ENOUGH_DATA); | 250 | ERR_R_MALLOC_FAILURE); |
258 | goto err; | 251 | goto err; |
259 | } | 252 | } |
260 | /* | 253 | want -= chunk; |
261 | * This can't overflow because |len+want| | 254 | while (chunk > 0) { |
262 | * didn't overflow. | 255 | i = BIO_read(in, &(b->data[len]), chunk); |
263 | */ | 256 | if (i <= 0) { |
264 | len += i; | 257 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, |
265 | chunk -= i; | 258 | ASN1_R_NOT_ENOUGH_DATA); |
259 | goto err; | ||
260 | } | ||
261 | /* | ||
262 | * This can't overflow because |len+want| | ||
263 | * didn't overflow. | ||
264 | */ | ||
265 | len += i; | ||
266 | chunk -= i; | ||
267 | } | ||
268 | if (chunk_max < INT_MAX/2) | ||
269 | chunk_max *= 2; | ||
266 | } | 270 | } |
267 | if (chunk_max < INT_MAX/2) | ||
268 | chunk_max *= 2; | ||
269 | } | 271 | } |
270 | if (off + c.slen < off) { | 272 | if (off + c.slen < off) { |
271 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); | 273 | ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); |