Hi Robert,
I re-wrote your patch for net-snmp-5.1.2-11 on RHEL4.
and fixing double free problem patch will post bellows..
Thanks.
-Nagata
diff -Naurp net-snmp-5.1.2/snmplib/callback.c
net-snmp-5.1.2.n/snmplib/callback.c
--- net-snmp-5.1.2/snmplib/callback.c 2005-04-06 09:33:33.987781993 +0900
+++ net-snmp-5.1.2/snmplib/callback.c 2005-04-06 09:48:37.178229368 +0900
@@ -45,6 +45,10 @@
#include <net-snmp/library/callback.h>
#include <net-snmp/library/snmp_api.h>
+
+static void _remove_duplicates(void *ptr, int x, int y);
+
+
static struct snmp_gen_callback
*thecallbacks[MAX_CALLBACK_IDS][MAX_CALLBACK_SUBIDS];
@@ -281,11 +285,34 @@ snmp_unregister_callback(int major, int
return count;
}
+static void
+_remove_duplicates(void *ptr, int x, int y)
+{
+ struct snmp_gen_callback *scp = NULL, *next = NULL;
+ int i,j;
+ for (i=x; i < MAX_CALLBACK_IDS; i++) {
+ for (j=y; j < MAX_CALLBACK_SUBIDS; j++) {
+ scp = thecallbacks[i][j];
+ while (scp != NULL) {
+ next=scp->next;
+ if ((NULL != scp->sc_callback) &&
+ (scp->sc_client_arg != NULL) &&
+ (scp->sc_client_arg == ptr)) {
+ DEBUGMSGTL(("callback", "duplicate client arg\n"));
+ scp->sc_client_arg = NULL;
+ }
+ scp = next;
+ }
+ }
+ }
+}
+
void
clear_callback(void)
{
unsigned int i = 0, j = 0;
struct snmp_gen_callback *scp = NULL, *next = NULL;
+ void *tmp_arg;
DEBUGMSGTL(("callback", "clear callback\n"));
for (i = 0; i < MAX_CALLBACK_IDS; i++) {
@@ -293,8 +320,24 @@ clear_callback(void)
scp = thecallbacks[i][j];
while (scp != NULL) {
next = scp->next;
- if (scp->sc_client_arg != NULL)
- SNMP_FREE(scp->sc_client_arg);
+
+ /*
+ * if there is a client arg, check for duplicates
+ * and then free it.
+ */
+ if ((NULL != scp->sc_callback) &&
+ (scp->sc_client_arg != NULL)) {
+ /*
+ * save the client arg, then set it to null so that it
+ * won't look like a duplicate, then check for duplicates
+ * starting at the current i,j (earlier dups should have
+ * already been found) and free the pointer.
+ */
+ tmp_arg = scp->sc_client_arg;
+ scp->sc_client_arg = NULL;
+ _remove_duplicates(tmp_arg, i, j);
+ free(tmp_arg);
+ }
SNMP_FREE(scp);
scp = next;
}