From 932bed61bd2b90b431d50b57f20785fc862bfa89 Mon Sep 17 00:00:00 2001 From: bojan Date: Sat, 21 Feb 2009 21:40:07 +0000 Subject: Fix apr_memcache_multgetp memory corruption and incorrect error handling. Patch by Sami Tolvanen . PR 46588. Sync CHANGES file from 1.4.x. git-svn-id: http://svn.apache.org/repos/asf/apr/apr-util/trunk@746592 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 12 ++++++++++++ memcache/apr_memcache.c | 46 +++++++++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index e9450f1a..3c9cc786 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,18 @@ Changes with APR-util 2.0.0 Changes with APR-util 1.4.0 + *) Fix apr_memcache_multgetp memory corruption and incorrect error + handling. PR 46588 [Sami Tolvanen ] + + *) Fix memcache memory leak with persistent connections. + PR 46482 [Sami Tolvanen ] + + *) Add Oracle 11 support. [Bojan Smojver] + + *) apr_dbd_freetds: Avoid segfault when process is NULL. + Do no print diagnostics to stderr. Never allow driver to exit + process. [Bojan Smojver] + *) Do not include apr.h and apr_errno.h from system search path in apu_errno.h. PR 46487 [Rainer Jung ] diff --git a/memcache/apr_memcache.c b/memcache/apr_memcache.c index e74454af..d244d564 100644 --- a/memcache/apr_memcache.c +++ b/memcache/apr_memcache.c @@ -1128,7 +1128,8 @@ apr_memcache_add_multget_key(apr_pool_t *data_pool, apr_hash_set(*values, value->key, klen, value); } -static void mget_conn_result(int up, +static void mget_conn_result(int serverup, + int connup, apr_status_t rv, apr_memcache_t *mc, apr_memcache_server_t *ms, @@ -1140,9 +1141,16 @@ static void mget_conn_result(int up, apr_int32_t j; apr_memcache_value_t* value; - if (!up) { + apr_hash_set(server_queries, &ms, sizeof(ms), NULL); + + if (connup) { + ms_release_conn(ms, conn); + } else { ms_bad_conn(ms, conn); - apr_memcache_disable_server(mc, ms); + + if (!serverup) { + apr_memcache_disable_server(mc, ms); + } } for (j = 1; j < server_query->query_vec_count ; j+=2) { @@ -1155,10 +1163,6 @@ static void mget_conn_result(int up, } } } - - ms_release_conn(ms, conn); - - apr_hash_set(server_queries, &ms, sizeof(ms), NULL); } APU_DECLARE(apr_status_t) @@ -1265,6 +1269,18 @@ apr_memcache_multgetp(apr_memcache_t *mc, rv = apr_pollset_create(&pollset, apr_hash_count(server_queries), temp_pool, 0); if (rv != APR_SUCCESS) { + query_hash_index = apr_hash_first(temp_pool, server_queries); + + while (query_hash_index) { + void *v; + apr_hash_this(query_hash_index, NULL, NULL, &v); + server_query = v; + query_hash_index = apr_hash_next(query_hash_index); + + mget_conn_result(TRUE, TRUE, rv, mc, server_query->ms, server_query->conn, + server_query, values, server_queries); + } + return rv; } @@ -1287,7 +1303,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, } if (rv != APR_SUCCESS) { - mget_conn_result(FALSE, rv, mc, ms, conn, + mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, server_query, values, server_queries); continue; } @@ -1319,7 +1335,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, if (rv != APR_SUCCESS) { apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, rv, mc, ms, conn, + mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, server_query, values, server_queries); queries_sent--; continue; @@ -1349,7 +1365,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, if (value) { - if (len > 0) { + if (len >= 0) { apr_bucket_brigade *bbb; apr_bucket *e; @@ -1358,7 +1374,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, if (rv != APR_SUCCESS) { apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, rv, mc, ms, conn, + mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, server_query, values, server_queries); queries_sent--; continue; @@ -1370,7 +1386,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, if (rv != APR_SUCCESS) { apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, rv, mc, ms, conn, + mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, server_query, values, server_queries); queries_sent--; continue; @@ -1379,7 +1395,7 @@ apr_memcache_multgetp(apr_memcache_t *mc, rv = apr_brigade_destroy(conn->bb); if (rv != APR_SUCCESS) { apr_pollset_remove (pollset, &activefds[i]); - mget_conn_result(FALSE, rv, mc, ms, conn, + mget_conn_result(FALSE, FALSE, rv, mc, ms, conn, server_query, values, server_queries); queries_sent--; continue; @@ -1430,13 +1446,13 @@ apr_memcache_multgetp(apr_memcache_t *mc, conn = server_query->conn; ms = server_query->ms; - mget_conn_result(TRUE, rv, mc, ms, conn, + mget_conn_result(TRUE, (rv == APR_SUCCESS), rv, mc, ms, conn, server_query, values, server_queries); continue; } - apr_pool_clear(temp_pool); apr_pollset_destroy(pollset); + apr_pool_clear(temp_pool); return APR_SUCCESS; } -- cgit v1.2.1