From: "Dr. Stephen Henson" <steve () openssl org>
To: Andy Grimm <agrimm () rpath com>
Cc: Stefan Fritsch <sf () debian org>, Kees Cook <kees () ubuntu com>,
        Pierre Joye <pierre.php () gmail com>,
        "Steven M. Christey" <coley () linus mitre org>,
        Daniel Stenberg <daniel () haxx se>, curl-security () haxx se,
        secalert () redhat com, security () debian org, security () suse de,
        security () ubuntu com, Joe Orton <jorton () redhat com>, security () php net,
        "Michael K. Johnson" <johnsonm () rpath com>,
        Kurt Roeckx <kurt () roeckx be>
Subject: Re: [PATCH] memory consumption (DoS) vulnerability involving libcurl
Message-ID: <20100111011852.GA14391 () openssl org>

...

I've attached a patch which uses an alternative technique. The main problem is
that the ex_data free function pointer is removed when
CRYPTO_cleanup_all_ex_data() is called. If the compression structure is
cleaned up directly this problem is avoided:

Index: crypto/comp/c_zlib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/comp/c_zlib.c,v
retrieving revision 1.22
diff -u -r1.22 c_zlib.c
--- crypto/comp/c_zlib.c	13 Dec 2008 17:19:40 -0000	1.22
+++ crypto/comp/c_zlib.c	8 Jan 2010 23:56:13 -0000
@@ -136,15 +136,6 @@
 
 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 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 @@
 			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;

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

