From a6532aa364e350224dcace082484a7cc58d678dc Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 10 Aug 2015 12:19:00 -0400 Subject: [PATCH 41/45] 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!) (cherry picked from commit a799c4670f2e6f6be1fc9a2828dc4a0f738d3021) (cherry picked from commit 29c669e43e16611a290e1c82dfdcf5b51903319e) --- ldap/servers/slapd/dse.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c index 61e2629..e8e393b 100644 --- a/ldap/servers/slapd/dse.c +++ b/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; -- 1.9.3