andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 83068484723e043e424b460c3073021b26e8dfa0 Mon Sep 17 00:00:00 2001
dc8c34
From: Ludwig Krispenz <lkrispen@redhat.com>
dc8c34
Date: Tue, 12 May 2015 10:24:29 +0200
dc8c34
Subject: [PATCH 329/329] Ticket 48149 - ns-slapd double free or corruption
dc8c34
 crash
dc8c34
dc8c34
Bug Description:  if the per file statistics are retrived from
dc8c34
                  the BDB backend, there is a race condition, which
dc8c34
                  corrupts the memory allcated for the statistics.
dc8c34
                  It happens id a new file with a longer backend/filename
dc8c34
                  is openend between the alloaction for the statistics
dc8c34
                  data and the actual populating if it
dc8c34
dc8c34
Fix Description:   The bug is in BDB and there is a fix from Oracle for the
dc8c34
                   latest versions, it is unclear if it will be backported
dc8c34
                   to the versions used in current supported389 platforms.
dc8c34
dc8c34
                   A fix in DS code is to lock the open calls from the
dc8c34
                   file statistic call
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/48149
dc8c34
dc8c34
Reviewed by: ?
dc8c34
dc8c34
(cherry picked from commit d620bb644a9b71ca9259edba42d62058e628cc0a)
dc8c34
---
dc8c34
 ldap/servers/slapd/back-ldbm/dblayer.c | 30 +++++++++++++++++++++---------
dc8c34
 1 file changed, 21 insertions(+), 9 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
index b25fccb..031523c 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
dc8c34
@@ -97,15 +97,19 @@
dc8c34
 #include "dblayer.h"
dc8c34
 
dc8c34
 #if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4100
dc8c34
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval)    \
dc8c34
+#define DB_OPEN(priv, oflags, db, txnid, file, database, type, flags, mode, rval)    \
dc8c34
 {                                                                              \
dc8c34
     if (((oflags) & DB_INIT_TXN) && ((oflags) & DB_INIT_LOG))                  \
dc8c34
     {                                                                          \
dc8c34
+        if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock);                             \
dc8c34
         (rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags)|DB_AUTO_COMMIT, (mode)); \
dc8c34
+        if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock);                             \
dc8c34
     }                                                                          \
dc8c34
     else                                                                       \
dc8c34
     {                                                                          \
dc8c34
+        if ((priv)) slapi_rwlock_rdlock((priv)->dblayer_env_lock);                             \
dc8c34
         (rval) = ((db)->open)((db), (txnid), (file), (database), (type), (flags), (mode)); \
dc8c34
+        if ((priv)) slapi_rwlock_unlock((priv)->dblayer_env_lock);                             \
dc8c34
     }                                                                          \
dc8c34
 }
dc8c34
 /* 608145: db4.1 and newer does not require exclusive lock for checkpointing 
dc8c34
@@ -113,7 +117,7 @@
dc8c34
 #define DB_CHECKPOINT_LOCK(use_lock, lock) ;
dc8c34
 #define DB_CHECKPOINT_UNLOCK(use_lock, lock) ;
dc8c34
 #else /* older then db 41 */
dc8c34
-#define DB_OPEN(oflags, db, txnid, file, database, type, flags, mode, rval)    \
dc8c34
+#define DB_OPEN(env, oflags, db, txnid, file, database, type, flags, mode, rval)    \
dc8c34
     (rval) = (db)->open((db), (file), (database), (type), (flags), (mode))
dc8c34
 #define DB_CHECKPOINT_LOCK(use_lock, lock) if(use_lock) slapi_rwlock_wrlock(lock);
dc8c34
 #define DB_CHECKPOINT_UNLOCK(use_lock, lock) if(use_lock) slapi_rwlock_unlock(lock);
dc8c34
@@ -2225,7 +2229,7 @@ int dblayer_instance_start(backend *be, int mode)
dc8c34
 
dc8c34
             abs_id2entry_file = slapi_ch_smprintf( "%s%c%s", inst_dirp, 
dc8c34
                     get_sep(inst_dirp), ID2ENTRY LDBM_FILENAME_SUFFIX);
dc8c34
-            DB_OPEN(mypEnv->dblayer_openflags,
dc8c34
+            DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dc8c34
                 dbp, NULL/* txnid */, abs_id2entry_file, subname, DB_BTREE,
dc8c34
                 open_flags, priv->dblayer_file_mode, return_value);
dc8c34
             dbp->close(dbp, 0);
dc8c34
@@ -2256,7 +2260,7 @@ int dblayer_instance_start(backend *be, int mode)
dc8c34
 #endif
dc8c34
             slapi_ch_free_string(&abs_id2entry_file);
dc8c34
         }
dc8c34
-        DB_OPEN(mypEnv->dblayer_openflags,
dc8c34
+        DB_OPEN(mypEnv, mypEnv->dblayer_openflags,
dc8c34
                 dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dc8c34
                 open_flags, priv->dblayer_file_mode, return_value);
dc8c34
         if (0 != return_value) {
dc8c34
@@ -2533,7 +2537,7 @@ dblayer_get_aux_id2entry_ext(backend *be, DB **ppDB, DB_ENV **ppEnv,
dc8c34
     }
dc8c34
 
dc8c34
     PR_ASSERT(dblayer_inst_exists(inst, NULL));
dc8c34
-    DB_OPEN(envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dc8c34
+    DB_OPEN(mypEnv, envflags, dbp, NULL/* txnid */, id2entry_file, subname, DB_BTREE,
dc8c34
             dbflags, priv->dblayer_file_mode, rval);
dc8c34
     if (rval) {
dc8c34
         LDAPDebug(LDAP_DEBUG_ANY,
dc8c34
@@ -3085,7 +3089,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
dc8c34
         }
dc8c34
         abs_file_name = slapi_ch_smprintf("%s%c%s",
dc8c34
                 inst_dirp, get_sep(inst_dirp), file_name);
dc8c34
-        DB_OPEN(pENV->dblayer_openflags,
dc8c34
+        DB_OPEN(pENV, pENV->dblayer_openflags,
dc8c34
                 dbp, NULL/* txnid */, abs_file_name, subname, DB_BTREE,
dc8c34
                 open_flags, priv->dblayer_file_mode, return_value);
dc8c34
         dbp->close(dbp, 0);
dc8c34
@@ -3101,7 +3105,7 @@ dblayer_open_file(backend *be, char* indexname, int open_flag,
dc8c34
 
dc8c34
         slapi_ch_free_string(&abs_file_name);
dc8c34
     }
dc8c34
-    DB_OPEN(pENV->dblayer_openflags,
dc8c34
+    DB_OPEN(pENV, pENV->dblayer_openflags,
dc8c34
             dbp, NULL, /* txnid */ rel_path, subname, DB_BTREE,
dc8c34
             open_flags, priv->dblayer_file_mode, return_value);
dc8c34
 #if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR == 4100
dc8c34
@@ -4743,6 +4747,7 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
dc8c34
 {
dc8c34
     dblayer_private *priv = NULL;
dc8c34
     DB_ENV *env = NULL;
dc8c34
+    int rc;
dc8c34
 
dc8c34
     PR_ASSERT(NULL != li);
dc8c34
     
dc8c34
@@ -4752,7 +4757,10 @@ int dblayer_memp_stat(struct ldbminfo *li, DB_MPOOL_STAT **gsp,
dc8c34
     env = priv->dblayer_env->dblayer_DB_ENV;
dc8c34
     PR_ASSERT(NULL != env);
dc8c34
     
dc8c34
-    return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
dc8c34
+    slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
dc8c34
+    rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
dc8c34
+    slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
dc8c34
+    return rc;
dc8c34
 }
dc8c34
 
dc8c34
 /* import wants this one */
dc8c34
@@ -4761,6 +4769,7 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
dc8c34
 {
dc8c34
     DB_ENV *env = NULL;
dc8c34
     dblayer_private *priv = NULL;
dc8c34
+    int rc;
dc8c34
 
dc8c34
     PR_ASSERT(NULL != inst);
dc8c34
 
dc8c34
@@ -4773,7 +4782,10 @@ int dblayer_memp_stat_instance(ldbm_instance *inst, DB_MPOOL_STAT **gsp,
dc8c34
     }
dc8c34
     PR_ASSERT(NULL != env);
dc8c34
 
dc8c34
-    return MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
dc8c34
+    slapi_rwlock_wrlock(priv->dblayer_env->dblayer_env_lock);
dc8c34
+    rc = MEMP_STAT(env, gsp, fsp, 0, (void *)slapi_ch_malloc);
dc8c34
+    slapi_rwlock_unlock(priv->dblayer_env->dblayer_env_lock);
dc8c34
+    return rc;
dc8c34
 }
dc8c34
 
dc8c34
 /* Helper functions for recovery */
dc8c34
-- 
dc8c34
1.9.3
dc8c34