On Thu, 10 Jul 2014, David Ramos wrote:
> Our UC-KLEE tool found an out-of-bounds read bug in 
> ssl3_get_key_exchange (ssl/s3_clnt.c) affecting the latest git revision 
> in the OpenSSL 1.0.1 branch (and probably others). The bug permits a 
> carefully-crafted ServerKeyExchange message to cause 1 or 2 bytes to be 
> read past the end of the packet buffer. The packet buffer tends to be 
> over-allocated, so I don't think this is likely to trigger a segfault. 
> It also doesn't appear to pose much of a threat to client-side 
> confidentiality (as far as I can tell).
>
> The out-of-bounds read is allowed due to improper bounds checking.
> 
> The packet is read by the call to ssl_get_message() on line 1291, which 
> returns the length of the packet. Depending on the choice of cipher, 
> lines 1359 (PSK), 1401 (SRP), 1486 (RSA), or 1540 (EDH) then read the 
> first two bytes from the buffer. This initial read may be out-of-bounds 
> since the return value of ssl_get_message() is never checked prior to 
> the read.
>
> There are subsequent bounds checks, but each of these is effectively 2 
> bytes "behind," so any of the subsequent reads may be out-of-bounds by 
> up to 2 bytes.

Hmm, I agree the n2s() calls can read past the end of the buffer, but the 
checks that then occur against param_len appear to be correct to me.

For example, the SRP case at 1399:
        if (alg_k & SSL_kSRP)
                {
                n2s(p,i);
                param_len=i+2;
                if (param_len > n)
                        {
                        al=SSL_AD_DECODE_ERROR;

Let's say a zero-length record was received, so n = 0.  The n2s() will 
read past the end, but param_len is set to the read length plus 2 for the 
length bytes, so param_len > n should indeed be the correct test there.  
No?

(param and param_len in this need to cover the entire record, as they're 
the input to the packet signature check.)


> I believe the fix would be to add an initial check (except for the EECDH 
> cipher) that rejects packets with n < 2, and then decrements n by 2. The 
> read on line 1757 also appears to need a bounds check.

Checking for n<2 makes sense, but decrementing n by 2 will be a double 
subtraction when param_len (which includes the 2) is subtracted from n.


Philip Guenther

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

Reply via email to