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 ca5075c..54e643f 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 0e503bf..8adf35f 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;