From: Graham Leggett Date: Tue, 25 May 2004 16:31:21 +0000 (+0000) Subject: Fix a segfault when requests for shared memory fails and returns X-Git-Tag: 2.0.50~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5a77297d847280f759ed2d97c55779c07adaa1b;p=thirdparty%2Fapache%2Fhttpd.git Fix a segfault when requests for shared memory fails and returns NULL. Fix a segfault caused by a lack of bounds checking on the cache. PR: 24801 Obtained from: Submitted by: Reviewed by: minfrin, bnicholes, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@103760 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 426050d38b5..4a5f33570c1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ Changes with Apache 2.0.50 + *) Fix a segfault when requests for shared memory fails and returns + NULL. Fix a segfault caused by a lack of bounds checking on the + cache. PR 24801 [Graham Leggett] + *) Throw an error message if an attempt is made to use the LDAPTrustedCA or LDAPTrustedCAType directives in a VirtualHost. PR 26390 [Brad Nicholes] diff --git a/STATUS b/STATUS index 2beb9b2afde..9bae8ea4b1b 100644 --- a/STATUS +++ b/STATUS @@ -1,5 +1,5 @@ APACHE 2.0 STATUS: -*-text-*- -Last modified at [$Date: 2004/05/25 16:19:09 $] +Last modified at [$Date: 2004/05/25 16:31:21 $] Release: @@ -76,13 +76,6 @@ PATCHES TO BACKPORT FROM 2.1 server/core.c: r1.279 +1: nd - *) Fix a segfault when requests for shared memory fails and returns - NULL. Fix a segfault caused by a lack of bounds checking on the - cache. - modules/experimental/util_ldap_cache_mgr.c r1.16 - PR 24801 - +1: minfrin, bnicholes, jim - *) Small fix to allow reverse proxying to an ftp server. Previously an attempt to do this would try and connect to 0.0.0.0, regardless of the server specified. diff --git a/modules/experimental/util_ldap_cache_mgr.c b/modules/experimental/util_ldap_cache_mgr.c index d91add149e8..dd808d2c456 100644 --- a/modules/experimental/util_ldap_cache_mgr.c +++ b/modules/experimental/util_ldap_cache_mgr.c @@ -99,7 +99,8 @@ void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size) #if APR_HAS_SHARED_MEMORY if (cache->rmm_addr) { /* allocate from shared memory */ - return (void *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, size)); + apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, size); + return block ? (void *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL; } else { /* Cache shm is not used */ @@ -115,7 +116,8 @@ const char *util_ald_strdup(util_ald_cache_t *cache, const char *s) #if APR_HAS_SHARED_MEMORY if (cache->rmm_addr) { /* allocate from shared memory */ - char *buf = (char *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, strlen(s)+1)); + apr_rmm_off_t block = apr_rmm_calloc(cache->rmm_addr, strlen(s)+1); + char *buf = block ? (char *)apr_rmm_addr_get(cache->rmm_addr, block) : NULL; if (buf) { strcpy(buf, s); return buf; @@ -262,9 +264,13 @@ util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st, return NULL; #if APR_HAS_SHARED_MEMORY - if (!st->cache_rmm) + if (!st->cache_rmm) { return NULL; - cache = (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t))); + } + else { + apr_rmm_off_t block = apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t)); + cache = block ? (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, block) : NULL; + } #else cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1); #endif @@ -362,22 +368,40 @@ void util_ald_cache_insert(util_ald_cache_t *cache, void *payload) int hashval; util_cache_node_t *node; - if (cache == NULL || payload == NULL) + /* sanity check */ + if (cache == NULL || payload == NULL) { return; + } - if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) + /* check if we are full - if so, try purge */ + if (cache->numentries >= cache->maxentries) { + util_ald_cache_purge(cache); + if (cache->numentries >= cache->maxentries) { + /* if the purge was not effective, we leave now to avoid an overflow */ + return; + } + } + + /* should be safe to add an entry */ + if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) { return; + } + /* populate the entry */ cache->inserts++; hashval = (*cache->hash)(payload) % cache->size; node->add_time = apr_time_now(); node->payload = (*cache->copy)(cache, payload); node->next = cache->nodes[hashval]; cache->nodes[hashval] = node; - if (++cache->numentries == cache->fullmark) + + /* if we reach the full mark, note the time we did so + * for the benefit of the purge function + */ + if (++cache->numentries == cache->fullmark) { cache->marktime=apr_time_now(); - if (cache->numentries >= cache->maxentries) - util_ald_cache_purge(cache); + } + } void util_ald_cache_remove(util_ald_cache_t *cache, void *payload)