Re: [libcrypto] fix short ASN1 reads

2016-05-20 Thread Ted Unangst
Brent Cook wrote:
> 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?

shit. yes, let's get this fixed and then think about new patches.



[libcrypto] fix short ASN1 reads

2016-05-20 Thread Brent Cook
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 -   1.14
+++ asn1/a_d2i_fp.c 20 May 2016 11:21:14 -
@@ -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);