Bug 758060 - (CVE-2012-2110) VUL-0: CVE-2012-2110: incorrect integer conversions in OpenSSL can result in memory corruption.
(CVE-2012-2110)
VUL-0: CVE-2012-2110: incorrect integer conversions in OpenSSL can result in ...
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P2 - High : Major
: ---
Assigned To: Security Team bot
Security Team bot
maint:released:sle11-sp1:47146 maint:...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-04-19 14:36 UTC by Matthias Weckbecker
Modified: 2022-04-05 13:04 UTC (History)
3 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
0.9.8v-0.9.8w.diff (32.89 KB, patch)
2012-04-24 10:06 UTC, Marcus Meissner
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Weckbecker 2012-04-19 14:36:19 UTC
Incorrect integer conversions in OpenSSL can result in memory corruption.
--------------------------------------------------------------------------

CVE-2012-2110

This advisory is intended for system administrators and developers exposing
OpenSSL in production systems to untrusted data.

asn1_d2i_read_bio in OpenSSL contains multiple integer errors that can cause
memory corruption when parsing encoded ASN.1 data. This error can be exploited
on systems that parse untrusted data, such as X.509 certificates or RSA public
keys.

The following context structure from asn1.h is used to record the current state
of the decoder:

typedef struct asn1_const_ctx_st
{
    const unsigned char *p;/* work char pointer */
    int eos;    /* end of sequence read for indefinite encoding */
    int error;  /* error code to use when returning an error */
    int inf;    /* constructed if 0x20, indefinite is 0x21 */
    int tag;    /* tag from last 'get object' */
    int xclass; /* class from last 'get object' */
    long slen;  /* length of last 'get object' */
    const unsigned char *max; /* largest value of p allowed */
    const unsigned char *q;/* temporary variable */
    const unsigned char **pp;/* variable */
    int line;   /* used in error processing */
} ASN1_const_CTX;

These members are populated via calls to ASN1_get_object and asn1_get_length
which have the following prototypes

int ASN1_get_object(const unsigned char **pp,
                    long *plength,
                    int *ptag,
                    int *pclass,
                    long omax);

int asn1_get_length(const unsigned char **pp,
                    int *inf,
                    long *rl,
                    int max);

The lengths are always stored as signed longs, however, asn1_d2i_read_bio
casts ASN1_const_CTX->slen to a signed int in multiple locations. This
truncation can result in numerous conversion problems.

The most visible example on x64 is this cast incorrectly interpreting the
result of asn1_get_length.

222             /* suck in c.slen bytes of data */
223             want=(int)c.slen;

A simple way to demonstrate this is to prepare a DER certificate that contains
a length with the 31st bit set, like so

$ dumpasn1 testcase.crt
0 NDEF: [PRIVATE 3] {
   2 2147483648:   [1]
        ...
   }

Breakpoint 2, asn1_d2i_read_bio (in=0x9173a0, pb=0x7fffffffd8f0) at a_d2i_fp.c:224
224             if (want > (len-off))
(gdb) list
219             }
220         else
221             {
222             /* suck in c.slen bytes of data */
223             want=(int)c.slen;
224             if (want > (len-off))
225                 {
226                 want-=(len-off);
227                 if (!BUF_MEM_grow_clean(b,len+want))
228                     {
(gdb) p c.slen
$18 = 2147483648
(gdb) p want
$19 = -2147483648

This results in an inconsistent state, and will lead to memory corruption.

--------------------
Affected Software
------------------------

All versions of OpenSSL on all platforms up to and including version 1.0.1 are
affected.

Some attack vectors require an I32LP64 architecture, others do not.

--------------------
Consequences
-----------------------

In order to explore the subtle problems caused by this, an unrelated bug in the
OpenSSL allocator wrappers must be discussed.

It is generally expected that the realloc standard library routine should support
reducing the size of a buffer, as well as increasing it. As ISO C99 states "The
realloc function deallocates the old object pointed to by ptr and returns a
pointer to a new object that has the size specified by size. The contents of the
new object shall be the same as that of the old object prior to deallocation,
up to the lesser of the new and old sizes."

However, the wrapper routines from OpenSSL do not support shrinking a buffer,
due to this code:

void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, int line)
{
    /* ... */
    ret=malloc_ex_func(num,file,line);
    if(ret)
        {
        memcpy(ret,str,old_len);
        OPENSSL_cleanse(str,old_len);
        free_func(str);
        }
    /* ... */
    return ret;
}

The old data is always copied over, regardless of whether the new size will be
enough. This allows us to turn this truncation into what is effectively:

    memcpy(heap_buffer, <attacker controlled buffer>, <attacker controlled size>);

We can reach this code by simply causing an integer to be sign extended and
truncated multiple times. These two protoypes are relevant:

int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);

void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, int line);

BUF_MEM_grow_clean accepts a size_t, but the subroutine it uses to handle the
allocation only accepts a 32bit signed integer. We can exploit this by
providing a large amount of data to OpenSSL, and causing the length calculation
here to become negative:

            /* suck in c.slen bytes of data */
            want=(int)c.slen;
            if (want > (len-off))
                {
                want-=(len-off);
                if (!BUF_MEM_grow_clean(b,len+want))
                    {
                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
                    goto err;
                    }

Because want is a signed int, the sign extension to size_t for
BUF_MEM_grow_clean means an unexpectedly size_t is produced. An
example is probably helpful:

(gdb) bt
#0  asn1_d2i_read_bio (in=0x9173a0, pb=0x7fffffffd8f0) at a_d2i_fp.c:223
#1  0x0000000000524ce8 in ASN1_item_d2i_bio (it=0x62d740, in=0x9173a0, x=0x0) at a_d2i_fp.c:112
#2  0x000000000054c132 in d2i_X509_bio (bp=0x9173a0, x509=0x0) at x_all.c:150
#3  0x000000000043b7a7 in load_cert (err=0x8a1010, file=0x0, format=1, pass=0x0, e=0x0, cert_descrip=0x5ebcc0 "Certificate") at apps.c:819
#4  0x0000000000422422 in x509_main (argc=0, argv=0x7fffffffe458) at x509.c:662
#5  0x00000000004032d9 in do_cmd (prog=0x9123e0, argc=3, argv=0x7fffffffe440) at openssl.c:489
#6  0x0000000000402ee6 in main (Argc=3, Argv=0x7fffffffe440) at openssl.c:381
(gdb) list
218                 want=HEADER_SIZE;
219             }
220         else 
221             {
222             /* suck in c.slen bytes of data */
223             want=(int)c.slen;
224             if (want > (len-off))
225                 {
226                 want-=(len-off);
227                 if (!BUF_MEM_grow_clean(b,len+want))
(gdb) pt len
type = int
(gdb) pt want
type = int
(gdb) p len
$28 = 1431655797
(gdb) p want
$29 = 2147483646
(gdb) p len+want
$30 = -715827853
(gdb) s
BUF_MEM_grow_clean (str=0x917440, len=18446744072993723763) at buffer.c:133
(gdb) p/x len
$31 = 0xffffffffd5555573

Here len+want wraps to a negative value, which is sign extended to a large
size_t for BUF_MEM_grow_clean. Now the call to CRYPTO_realloc_clean() truncates
this back into a signed int:

CRYPTO_realloc_clean (str=0x7fff85be4010, old_len=1908874388, num=477218632, file=0x626661 "buffer.c", line=149) at mem.c:369

Now old_len > num, which openssl does not handle, resulting in this:

 ret = malloc_ex_func(num, file, line);

 memcpy(ret, str, old_len);

Effectively a textbook heap overflow. It is likely this code is reachable via
the majority of the d2i BIO interfaces and their wrappers, so most applications
that handle untrusted data via OpenSSL should take action.

Note that even if you do not use d2i_* calls directly, many of the higher level
APIs will use it indirectly for you. Producing DER data to demonstrate this
is relatively easy for both x86 and x64 architectures.

-------------------
Solution
-----------------------

The OpenSSL project has provided an updated version to resolve this issue.

http://www.openssl.org/
http://www.openssl.org/news/secadv_20120419.txt

-------------------
Credit
-----------------------

This bug was discovered by Tavis Ormandy, Google Security Team.

Additional thanks to Adam Langley also of Google for analysis and designing a fix.

-- 
-------------------------------------
taviso@cmpxchg8b.com | pgp encrypted mail preferred
-------------------------------------------------------
Comment 1 Matthias Weckbecker 2012-04-19 14:38:24 UTC
Posted via full-disclosure at [1]

[1] http://lists.grok.org.uk/pipermail/full-disclosure/2012-April/086585.html
Comment 2 Swamp Workflow Management 2012-04-19 14:39:20 UTC
The SWAMPID for this issue is 46885.
This issue was rated as important.
Please submit fixed packages until 2012-04-26.
When done, please reassign the bug to security-team@suse.de.
Patchinfo will be handled by security team.
Comment 4 Marcus Meissner 2012-04-20 11:14:47 UTC
perl /suse/meissner/bin/addnote CVE-2012-2110 "We are aware of this problem and it affects all openssl versions in our current products. Normal SSL and TLS communication services are however not affected directly by this, so it is not exploitable for SSL/TLS connections. More information can be found <a href=\"http//www.openssl.org/news/secadv_20120419.txt\">in the openssl adivsory</a>. We will be publishing updates."
Comment 5 Matthias Weckbecker 2012-04-22 12:43:55 UTC
Tavis Ormany of Google also provided the following test case:

$ printf "\xe3\x80\x81\x84\xe3\x80\x00\x00\x00\x00" | openssl x509 -inform DER

Actual result on unfixed openssl: sigsegv
Expected result: no crash :)

Note: Test case is only applicable to x86_64. Nevertheless, other architectures
will also require patching.
Comment 6 Sebastian Krahmer 2012-04-23 06:38:59 UTC
http://lock.cmpxchg8b.com/openssl-1.0.1-testcase-32bit.crt.gz

SHA-256: ac7acb168a6bfd65375eeec072acbf904f0f10e3bc5588c020aed4df4712d066
Comment 8 Guan Jun He 2012-04-23 06:55:25 UTC

patch submitted to Base:system/12.1/11.4.
Comment 10 Guan Jun He 2012-04-23 07:53:25 UTC
(In reply to comment #8)
> 
> patch submitted to Base:system/12.1/11.4.

submitted to sle11/sle10.

fixed.
Comment 14 Sebastian Krahmer 2012-04-24 07:52:43 UTC
The fix seems to be incomplete:

http://marc.info/?l=openssl-dev&m=133525318514423&w=2

(CVE-2012-2131)
Comment 15 Sebastian Krahmer 2012-04-24 07:55:07 UTC
For the 0.9.8v version. Any dist where we have that version?
Comment 16 Marcus Meissner 2012-04-24 10:06:23 UTC
Created attachment 487682 [details]
0.9.8v-0.9.8w.diff

the 0.9.8v->0.9.8w diff 

interesting i think just the buffer.c change
Comment 18 Guan Jun He 2012-05-03 08:14:20 UTC
patch for CVE-2012-2131 has been submitted to sle11 and sle10.

fixed.
Comment 22 Guan Jun He 2012-05-10 06:50:19 UTC
(In reply to comment #21)
> (In reply to comment #18)
> > patch for CVE-2012-2131 has been submitted to sle11 and sle10.
> > 
> > fixed.
> 
> Hi Guan Jun:
> My customer Tencent ask to supply rpm package for this bug on sles10 and sles11
> , where can I get it ?

it's fixed as normal update, so soon there will be a security update.
Comment 25 Jun Hu 2012-05-16 04:20:06 UTC
Guan Jun, Can you tell me the time of normal update, My customer asks me to give the time deadline.
Comment 26 Marcus Meissner 2012-05-16 07:31:21 UTC
This is in QA verification right now, we expect release any day.
Comment 27 Matthias Weckbecker 2012-05-16 11:58:01 UTC
We just released OpenSSL for all code 11 based products. Code 10 will 
follow shortly (probably even today or next week).
Comment 28 Swamp Workflow Management 2012-05-16 15:38:43 UTC
Update released for: libopenssl-devel, libopenssl0_9_8, libopenssl0_9_8-32bit, libopenssl0_9_8-x86, openssl, openssl-debuginfo, openssl-debugsource, openssl-doc
Products:
SLE-DEBUGINFO 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLE-DESKTOP 11-SP1 (i386, x86_64)
SLE-DESKTOP 11-SP1-FOR-SP2 (i386, x86_64)
SLE-SDK 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLE-SDK 11-SP1-FOR-SP2 (i386, ia64, ppc64, s390x, x86_64)
SLE-SERVER 11-SP1 (i386, ia64, ppc64, s390x, x86_64)
SLE-SERVER 11-SP1-FOR-SP2 (i386, ia64, ppc64, s390x, x86_64)
SLE-SERVER 11-SP1-TERADATA (x86_64)
SLES4VMWARE 11-SP1 (i386, x86_64)
Comment 32 Swamp Workflow Management 2012-05-22 18:08:51 UTC
Update released for: openssl, openssl-devel, openssl-doc
Products:
SUSE-CORE 9-SP3-TERADATA (x86_64)
Comment 33 Swamp Workflow Management 2012-05-22 18:09:14 UTC
Update released for: openssl, openssl-32bit, openssl-debuginfo, openssl-devel, openssl-devel-32bit, openssl-doc
Products:
SLE-SERVER 10-SP3-TERADATA (x86_64)
Comment 34 Swamp Workflow Management 2012-05-22 19:15:37 UTC
Update released for: openssl, openssl-32bit, openssl-64bit, openssl-debuginfo, openssl-devel, openssl-devel-32bit, openssl-devel-64bit, openssl-doc, openssl-x86
Products:
SLE-DEBUGINFO 10-SP4 (i386, ia64, ppc, s390x, x86_64)
SLE-DESKTOP 10-SP4 (i386, x86_64)
SLE-SDK 10-SP4 (i386, ia64, ppc, s390x, x86_64)
SLE-SERVER 10-SP4 (i386, ia64, ppc, s390x, x86_64)
Comment 36 Matthias Weckbecker 2012-05-23 10:19:14 UTC
released
Comment 37 Swamp Workflow Management 2012-05-30 17:53:52 UTC
Update released for: openssl, openssl-32bit, openssl-debuginfo, openssl-devel, openssl-devel-32bit, openssl-doc
Products:
SLE-SERVER 10-SP3-LTSS (i386, s390x, x86_64)
Comment 38 Swamp Workflow Management 2012-08-22 12:03:19 UTC
The SWAMPID for this issue is 48827.
This issue was rated as important.
Please submit fixed packages until 2012-08-29.
When done, please reassign the bug to security-team@suse.de.
Patchinfo will be handled by security team.
Comment 39 Marcus Meissner 2012-08-22 12:05:35 UTC
we missed updating the compat-openssl097g packages on SLE10 and SLE11.

Guan, can you check these and merge all fixes we might have missed into them
since the last update?

in the sles9 0.9.7 openssl we have these fixes:

-------------------------------------------------------------------
Thu May  3 10:39:39 UTC 2012 - gjhe@suse.com

- fix bug[bnc#758060] - VUL-0: CVE-2012-2110: incorrect integer 
  conversions in OpenSSL can result in memory corruption.
  CVE-2012-2110
  CVE-2012-2131

-------------------------------------------------------------------
Thu Feb  9 14:05:30 CET 2012 - meissner@suse.de

- fix security bug [bnc#739719] -  various security issues
  Uninitialized SSL 3.0 Padding (CVE-2011-4576)
  SGC Restart DoS Attack (CVE-2011-4619)

  Not affected by:
  - Malformed RFC 3779 Data Can Cause Assertion Failures (CVE-2011-4577)
  - Double-free in Policy Checks (CVE-2011-4109)
    (No x509 policy handling in 0.9.7)
  - DTLS DoS Attack CVE-2012-0050
  - DTLS Plaintext Recovery Attack (CVE-2011-4108)
    (DTLS only added to openssl 0.9.8, not present in 0.9.7)
Comment 40 Marcus Meissner 2012-08-22 12:05:51 UTC
reopen
Comment 41 Dong Mao Zhang 2012-08-30 06:38:22 UTC
fixed for compat-openssl097g

sle10 sr#21589

sle11 sr#21590
Comment 42 Marcus Meissner 2012-09-13 12:14:27 UTC
in above submit for compat-openssl097g these 2 CVEs probably were forgotten, (seem
to apply).
  Uninitialized SSL 3.0 Padding (CVE-2011-4576)
  SGC Restart DoS Attack (CVE-2011-4619)


they are not that severe as the integer conversion bug, which is fixed.
Comment 43 Marcus Meissner 2012-09-14 11:33:36 UTC
done.
Comment 44 Swamp Workflow Management 2012-09-18 09:12:50 UTC
Update released for: compat-openssl097g, compat-openssl097g-32bit, compat-openssl097g-debuginfo, compat-openssl097g-debuginfo-32bit, compat-openssl097g-debugsource
Products:
SLE-SAP-AIO 11-SP1 (x86_64)
Comment 45 Swamp Workflow Management 2012-09-19 15:01:24 UTC
Update released for: compat-openssl097g
Products:
SLE-DEBUGINFO 11-SP2 (x86_64)
SLE-DESKTOP 11-SP2 (x86_64)
SLE-SAP-AIO 11-SP2 (x86_64)
Comment 46 Swamp Workflow Management 2012-09-19 15:04:47 UTC
Update released for: compat-openssl097g, compat-openssl097g-32bit, compat-openssl097g-debuginfo
Products:
SLE-SERVER 10-SP3-TERADATA (x86_64)
Comment 47 Swamp Workflow Management 2012-09-19 15:05:38 UTC
Update released for: compat-openssl097g, compat-openssl097g-32bit, compat-openssl097g-64bit, compat-openssl097g-debuginfo, compat-openssl097g-x86
Products:
SLE-DESKTOP 10-SP4 (i386, x86_64)
SLE-SERVER 10-SP4 (i386, ia64, ppc, s390x, x86_64)
Comment 48 Swamp Workflow Management 2013-08-28 08:49:57 UTC
Update released for: openssl, openssl-devel, openssl-doc
Products:
SUSE-CORE 9-LTSS (i386, s390, s390x, x86_64)