]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fix a segfault when requests for shared memory fails and returns
authorGraham Leggett <minfrin@apache.org>
Tue, 25 May 2004 16:31:21 +0000 (16:31 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 25 May 2004 16:31:21 +0000 (16:31 +0000)
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

CHANGES
STATUS
modules/experimental/util_ldap_cache_mgr.c

diff --git a/CHANGES b/CHANGES
index 426050d38b58d36f1f96f99e11baabf506080199..4a5f33570c1d3ee2474bbc6901b74b8953e1fd04 100644 (file)
--- 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 2beb9b2afde53ebec7c02801615699f2b008ff53..9bae8ea4b1b36c35d80ce5911bc69f481acf073d 100644 (file)
--- 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.
index d91add149e81b867770ae313596e88c7046d5f31..dd808d2c456081f512ed87083ed6494594b28ca6 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)