Hi, Our errata patch for fixing large memory allocations in asn1_d2i_read_bio dropped the while (want > 0) loop, causing the function to only read chunk_max bytes once. This limits the max size read to 16k. This patch restores the outer loop. Noted on misc@
ftp http://ccd.serpro.gov.br/lcr/acserprorfbv3.crl openssl crl -in acserprorfbv3.crl -inform DER ok? Index: asn1/a_d2i_fp.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c,v retrieving revision 1.14 diff -u -p -u -p -r1.14 a_d2i_fp.c --- asn1/a_d2i_fp.c 4 May 2016 14:58:09 -0000 1.14 +++ asn1/a_d2i_fp.c 20 May 2016 11:21:14 -0000 @@ -236,36 +236,38 @@ asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) ASN1_R_TOO_LONG); goto err; } - /* - * Read content in chunks of increasing size - * so we can return an error for EOF without - * having to allocate the entire content length - * in one go. - */ - size_t chunk = want > chunk_max ? chunk_max : want; + while (want > 0) { + /* + * Read content in chunks of increasing size + * so we can return an error for EOF without + * having to allocate the entire content length + * in one go. + */ + size_t chunk = want > chunk_max ? chunk_max : want; - if (!BUF_MEM_grow_clean(b, len + chunk)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, - ERR_R_MALLOC_FAILURE); - goto err; - } - want -= chunk; - while (chunk > 0) { - i = BIO_read(in, &(b->data[len]), chunk); - if (i <= 0) { + if (!BUF_MEM_grow_clean(b, len + chunk)) { ASN1err(ASN1_F_ASN1_D2I_READ_BIO, - ASN1_R_NOT_ENOUGH_DATA); + ERR_R_MALLOC_FAILURE); goto err; } - /* - * This can't overflow because |len+want| - * didn't overflow. - */ - len += i; - chunk -= i; + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, + ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + /* + * This can't overflow because |len+want| + * didn't overflow. + */ + len += i; + chunk -= i; + } + if (chunk_max < INT_MAX/2) + chunk_max *= 2; } - if (chunk_max < INT_MAX/2) - chunk_max *= 2; } if (off + c.slen < off) { ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);