Forgot to cc [EMAIL PROTECTED]

On Mon, 04 Feb 2002, Samuel Meder wrote:

> 
> The bug occurs when reading objects that are bigger than the SSL
> record size from a SSL bio:
> 
> ASN1_d2i_bio calls BIO_read without checking that the amount received
> is equal to the amount requested (This causes a problem becuase
> BIO_read will never return more than a record worth of data when
> reading from a ssl bio). The following patch seems to fix the problem.
> 
> To make things clearer here is the current bit of problematic code in
> ASN1_d2i_bio with a few comments:
> 
>     for (;;)
>     {
>         if (want >= (len-off))
>         {
>             want-=(len-off);
> 
>             if (!BUF_MEM_grow(b,len+want))
>             {
>                 ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
>                 goto err;
>             }
>             i=BIO_read(in,&(b->data[len]),want);
>             if ((i < 0) && ((len-off) == 0))
>             {
>                 ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
>                 goto err;
>             }
>             if (i > 0)
>                 len+=i;
> =============================================================================
> When the header stradles a ssl record boundary, we will have i>0, but
> i<want. This can cause ASN1_get_object to return ASN1_R_TOO_LONG
> (which is seemingly ignored here) and will (I think) lead to accessing
> uninitialized data. Note that my patch doesn't address this one as I'm
> less sure of it.
> =============================================================================
> 
>         }
>         /* else data already loaded */
> 
>         p=(unsigned char *)&(b->data[off]);
>         c.p=p;
>         c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
>                               len-off);
>         if (c.inf & 0x80)
>         {
>             unsigned long e;
> 
>             e=ERR_GET_REASON(ERR_peek_error());
>             if (e != ASN1_R_TOO_LONG)
>                 goto err;
>             else
>                 ERR_get_error(); /* clear error */
>         }
>         i=c.p-p;/* header length */
>         off+=i; /* end of data */
> 
>         if (c.inf & 1)
>         {
>             /* no data body so go round again */
>             eos++;
>             want=HEADER_SIZE;
>         }
>         else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
>         {
>             /* eos value, so go back and read another header */
>             eos--;
>             if (eos <= 0)
>                 break;
>             else
>                 want=HEADER_SIZE;
>         }
>         else
>         {
>             /* suck in c.slen bytes of data */
>             want=(int)c.slen;
>             if (want > (len-off))
>             {
>                 want-=(len-off);
>                 if (!BUF_MEM_grow(b,len+want))
>                 {
>                     ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
>                     goto err;
>                 }
>                 i=BIO_read(in,&(b->data[len]),want);
>                 if (i <= 0)
>                 {
>                     ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
>                     goto err;
>                 }
>                 len+=i;
> =============================================================================
> Here we have a definite problem. Again if we hit the situation where
> i>0, but i<want, we just ignore this and return successfully.
> =============================================================================
>             }
>             off+=(int)c.slen;
>             if (eos <= 0)
>             {
>                 break;
>             }
>             else
>                 want=HEADER_SIZE;
>         }
>     }
> 
> I've attached a patch for the second problem, though I believe a
> similar thing should be done for the first.
> 
> /Sam

> diff -u -r openssl-0.9.6c/crypto/asn1/a_d2i_fp.c 
>openssl-0.9.6c-patched/crypto/asn1/a_d2i_fp.c
> --- openssl-0.9.6c/crypto/asn1/a_d2i_fp.c     Fri Apr 23 17:08:07 1999
> +++ openssl-0.9.6c-patched/crypto/asn1/a_d2i_fp.c     Sun Feb  3 14:26:45 2002
> @@ -169,13 +169,17 @@
>                                       
>ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
>                                       goto err;
>                                       }
> -                             i=BIO_read(in,&(b->data[len]),want);
> -                             if (i <= 0)
> -                                     {
> -                                     
>ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
> -                                     goto err;
> -                                     }
> -                             len+=i;
> +                                 while(want)
> +                                        {
> +                                        i=BIO_read(in,&(b->data[len]),want);
> +                                        if (i <= 0)
> +                                             {
> +                                             
>ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
> +                                             goto err;
> +                                             }
> +                                     len+=i;
> +                                        want-=i;
> +                                        }
>                               }
>                       off+=(int)c.slen;
>                       if (eos <= 0)
> 
> 
> 
> 
> 
> 
> 
> 
> 

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to