Modify compression code so it avoids using ex_data free functions. This
authorDr. Stephen Henson <steve@openssl.org>
Wed, 13 Jan 2010 18:57:40 +0000 (18:57 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 13 Jan 2010 18:57:40 +0000 (18:57 +0000)
stops applications that call CRYPTO_free_all_ex_data() prematurely leaking
memory.

CHANGES
crypto/comp/c_zlib.c

diff --git a/CHANGES b/CHANGES
index ca5075cc2314a3779a6b6b2e1b953a97032307bf..54e643f80f5728340b23863d96e74dbe19227a16 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 
  Changes between 0.9.8l (?) and 0.9.8m (?)  [xx XXX xxxx]
 
+  *) Modify compression code so it frees up structures without using the
+     ex_data callbacks. This works around a problem where some applications
+     call CRYPTO_free_all_ex_data() before application exit (e.g. when
+     restarting) then use compression (e.g. SSL with compression) later.
+     This results in significant per-connection memory leaks and
+     has caused some security issues including CVE-2008-1678 and
+     CVE-2009-4355.
+     [Steve Henson]
+
   *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
      connect (but not renegotiate) with servers which do not support RI.
      Until RI is more widely deployed this option is enabled by default.
index 0e503bf1772b39b00c366e55bc22bd390a0a7b02..8adf35f3fc9cfcdc52b7651358a51b8d81983f19 100644 (file)
@@ -136,15 +136,6 @@ struct zlib_state
 
 static int zlib_stateful_ex_idx = -1;
 
-static void zlib_stateful_free_ex_data(void *obj, void *item,
-       CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
-       {
-       struct zlib_state *state = (struct zlib_state *)item;
-       inflateEnd(&state->istream);
-       deflateEnd(&state->ostream);
-       OPENSSL_free(state);
-       }
-
 static int zlib_stateful_init(COMP_CTX *ctx)
        {
        int err;
@@ -188,6 +179,12 @@ static int zlib_stateful_init(COMP_CTX *ctx)
 
 static void zlib_stateful_finish(COMP_CTX *ctx)
        {
+       struct zlib_state *state =
+               (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
+                       zlib_stateful_ex_idx);
+       inflateEnd(&state->istream);
+       deflateEnd(&state->ostream);
+       OPENSSL_free(state);
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
        }
 
@@ -402,7 +399,7 @@ COMP_METHOD *COMP_zlib(void)
                        if (zlib_stateful_ex_idx == -1)
                                zlib_stateful_ex_idx =
                                        CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
-                                               0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
+                                               0,NULL,NULL,NULL,NULL);
                        CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
                        if (zlib_stateful_ex_idx == -1)
                                goto err;