]> granicus.if.org Git - apache/commitdiff
Fix a segfault when requests for shared memory fails and returns
authorGraham Leggett <minfrin@apache.org>
Sun, 23 May 2004 22:15:10 +0000 (22:15 +0000)
committerGraham Leggett <minfrin@apache.org>
Sun, 23 May 2004 22:15:10 +0000 (22:15 +0000)
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

CHANGES
modules/experimental/util_ldap_cache_mgr.c

diff --git a/CHANGES b/CHANGES
index 0f5b15062499680b5e1e2814be7fa96f97303c1c..ccf42ec70e1614632766abbad062ece66deb4a06 100644 (file)
--- 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]
index 5c32b01d82effc7eda37558477d868c9209e1ae2..392ba6584c16052d1fdf61a131f5c0ac8b6bd6c4 100644 (file)
@@ -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)