Browse Source

Ticket 47686 - removing chaining database links trigger valgrind read errors

Bug Description:  Plugins that remove their dse callback from the dse callback
                  function lead to invalid reads in dse_call_callback().

Fix Description:  In dse_call_callback(), save the pointers to the next callback,
                  and its plugin, before we call the callback function.  So in
                  case the callback function removes itself, we are not accessing
                  the freed callback pointer later on.

https://fedorahosted.org/389/ticket/47686

Reviewed by: nhosoi(Thanks!)
Mark Reynolds 10 years ago
parent
commit
a799c4670f
1 changed files with 8 additions and 5 deletions
  1. 8 5
      ldap/servers/slapd/dse.c

+ 8 - 5
ldap/servers/slapd/dse.c

@@ -2607,18 +2607,21 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int operation, int flags,
 
     if (pdse->dse_callback != NULL) {
         struct dse_callback *p = pdse->dse_callback;
+        struct dse_callback *next = NULL;
         int result = SLAPI_DSE_CALLBACK_OK;
 
         while (p != NULL) {
+            next = p->next;
             if ((p->operation & operation) && (p->flags & flags)) {
                 if(slapi_sdn_scope_test(slapi_entry_get_sdn_const(entryBefore), p->base, p->scope)){
                     if(NULL == p->slapifilter || slapi_vattr_filter_test(pb, entryBefore, p->slapifilter, 0) == 0){
+                        struct slapdplugin *plugin = p->plugin;
                         int plugin_started = 1;
 
-                        if(p->plugin){
+                        if(plugin){
                             /* this is a plugin callback, update the operation counter */
-                            slapi_plugin_op_started(p->plugin);
-                            if(!p->plugin->plg_started){
+                            slapi_plugin_op_started(plugin);
+                            if(!plugin->plg_started){
                                 /* must be a task function being called */
                                 result = SLAPI_DSE_CALLBACK_ERROR;
                                 PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,
@@ -2633,11 +2636,11 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int operation, int flags,
                         if(result < rc){
                             rc = result;
                         }
-                        slapi_plugin_op_finished(p->plugin);
+                        slapi_plugin_op_finished(plugin);
                     }
                 }
             }
-            p = p->next;
+            p = next;
         }
     }
     return rc;