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;
            }

Reply via email to