[icinga-checkins] icinga.org: icinga-core/master: Fix event broker callback functions self de-registering for callbacks

git at icinga.org git at icinga.org
Sat Jan 9 18:20:00 CET 2010


Module: icinga-core
Branch: master
Commit: a3616d192b55823c6c1ea43583119c40f9a3c7c0
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=a3616d192b55823c6c1ea43583119c40f9a3c7c0

Author: Hendrik Baecker <andurin at process-zero.de>
Date:   Sat Jan  9 18:08:31 2010 +0100

Fix event broker callback functions self de-registering for callbacks

closes #169

Sean Millichamp:
If a Nagios event broker callback function de-registers itself (via
neb_deregister_callback) while it is being called (from
neb_make_callbacks) there is a pointer problem.

neb_make_callbacks walks the callback linked list like this:

for(temp_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=temp_callback->next){
	callbackfunc=temp_callback->callback_func;
	cbresult=callbackfunc(callback_type,data);
	}

If callbackfunc() calls neb_deregister_callback then the memory address
pointed to by temp_callback is free()d and no longer valid, making the
temp_callback=temp_callback->next not valid (though if the memory hasn't
been overwritten yet it may work).

---

 AUTHORS        |    1 +
 Changelog      |    1 +
 base/nebmods.c |    7 +++++--
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index f7c7571..30052bc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -13,5 +13,6 @@ Mark Young
 Michael Friedrich
 Michael Luebben
 Opsera Ltd
+Sean Millichamp
 Tobias Scherbaum
 Ton Voon
diff --git a/Changelog b/Changelog
index 486a451..3a367ac 100644
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,7 @@ Icinga 1.0.x Change Log
 
 1.x - xx/xx/2010
 * core: fix segfault in cmd.cgi
+* core: fix event broker callback function self de-registering for callbacks (Sean Millichamp)
 
 1.0 Stable - 16/12/2009
 * core: create webserver conf.d dir if not existing
diff --git a/base/nebmods.c b/base/nebmods.c
index 93f178e..745687e 100644
--- a/base/nebmods.c
+++ b/base/nebmods.c
@@ -561,7 +561,7 @@ int neb_deregister_callback(int callback_type, int (*callback_func)(int,void *))
 
 /* make callbacks to modules */
 int neb_make_callbacks(int callback_type, void *data){
-	nebcallback *temp_callback=NULL;
+	nebcallback *temp_callback=NULL, *next_callback=NULL;
 	int (*callbackfunc)(int,void *);
 	register int cbresult=0;
 	int total_callbacks=0;
@@ -577,7 +577,10 @@ int neb_make_callbacks(int callback_type, void *data){
 	log_debug_info(DEBUGL_EVENTBROKER,1,"Making callbacks (type %d)...\n",callback_type);
 
 	/* make the callbacks... */
-	for(temp_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=temp_callback->next){
+	for(temp_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=next_callback){
+		/* Save temp_callback->next because if the callback function de-registers itself temp_callback's */
+		/* pointer isn't guaranteed to be usable anymore (neb_deregister_callback will free() it) */
+		next_callback=temp_callback->next;
 		callbackfunc=temp_callback->callback_func;
 		cbresult=callbackfunc(callback_type,data);
 





More information about the icinga-checkins mailing list