From: Graham Leggett Date: Sun, 23 May 2004 22:15:10 +0000 (+0000) Subject: Fix a segfault when requests for shared memory fails and returns X-Git-Tag: pre_ajp_proxy~235 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=47487278314b27282066a11e2712dd9930835c38;p=apache 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: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@103746 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0f5b150624..ccf42ec70e 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.1.0-dev [Remove entries to the current 2.0 section below, when backported] + *) 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/modules/experimental/util_ldap_cache_mgr.c b/modules/experimental/util_ldap_cache_mgr.c index 5c32b01d82..392ba6584c 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)