From: Leonardo Chiquitto <lchiquitto@suse.com>
Subject: Memory leak fixes from 5.4.2.1 to 5.4.4
References: bnc#833191

Merges the following upstream commits:

commit 7d57f2dd0b4391d39e69a432014ac8493c4b96a2
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Thu Apr 23 14:55:21 2009 +0000

    Fix memory leak in SCTP containers.

commit 2ec71fc35dc02e02b25ad5d50fb9cd46a2644382
Author: Wes Hardaker <hardaker@users.sourceforge.net>
Date:   Thu Apr 23 15:04:24 2009 +0000

    CHANGES: snmpd: patch from Tushar Gohad to clean up notification registerations during disman event mib cleanup processing.

commit f57c0b5e340d00e726bf140a3df8950e0185966e
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Wed Aug 5 15:12:06 2009 +0000

    Fix memory leak in UDP- and TCP-MIB.
    The data from raw_data are copied to cache, so it should be freed.

commit 772d8f93a25c45c007e3dd48cf7a019554661a72
Author: Dave Shield <dts12@users.sourceforge.net>
Date:   Wed Aug 5 19:05:47 2009 +0000

    CHANGES: snmpd: PATCHES: 2822337: Fix memory leak in ipAddressPrefixTable

commit f80d5ee1eead01af0d72537dac973cd74cbc8ec6
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Fri Oct 9 12:38:55 2009 +0000

    CHANGES: snmplib: PATCH:2871747: plug memory leak in OID processing.
    The memory leaked when small OID, which could fit pre-allocated vp->name_loc, was placed in different (allocated) one.

commit 26c21a6592dfce2110920091191c9a7268032f3e
Author: Dave Shield <dts12@users.sourceforge.net>
Date:   Mon Nov 30 14:49:14 2009 +0000

    CHANGES: agent: PATCH: 2883155: Fix memory leak in proxy handling.
    Patch supplied by Gowtham Thommandra.

commit e5b2a375e23f9bfd298b0f644a424263c0e0a540
Author: Dave Shield <dts12@users.sourceforge.net>
Date:   Tue Dec 1 12:31:35 2009 +0000

    CHANGES: agent: BUGS: 2822360: Fix memory leak when building table OIDs

commit f9d56472366bae44227523307293d3b47497326f
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Wed Dec 2 15:39:04 2009 +0000

    CHANGES: snmpd: Fixed invalid access to memory in TCP-MIB
    This partly reverts patch 17719 - the entries *are* used after raw_data container is freed. These entries should be freed when associated rowreq_ctx is freed.

commit d0f87d532abd43291090f9dd843135d280230645
Author: Wes Hardaker <hardaker@users.sourceforge.net>
Date:   Thu Jan 7 19:42:39 2010 +0000

    Patch from Stephen Hemminger to fix a minor memleak in cpu sysctrl fetching

commit 56544a1f1dcc5a65decc7b0bf34fa48461a31a75
Author: Wes Hardaker <hardaker@users.sourceforge.net>
Date:   Tue Nov 30 04:58:34 2010 +0000

    CHANGES: PATCH 3074918: from weizheng: check for CONTAINER_INSERT failures and react appropriately to avoid memory leaks

commit 0e913b536ebcc2c71b7c9ede362edda0da2b0ede
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Wed Dec 8 13:17:10 2010 +0000

    CHANGES: snmpd: add newly created/destroyed interfaces to ipv6IfTable

    The list of interfaces was never refreshed, now it is reloaded every time the
    table is accessed. I've also fixed a memory leak and optimized the loading
    of the list a bit.

commit 3bb294663e63e3d5b52f0307b47ad9e6d30b85d4
Author: Bart Van Assche <bvassche@users.sourceforge.net>
Date:   Thu May 12 09:03:02 2011 +0000

    CHANGES: snmplib: Fixed a memory leak in snmp_free_session().

commit eb217146fd54036ea4202bfef78bbf774d7e382d
Author: Jan Safranek <jsafranek@users.sourceforge.net>
Date:   Wed Jan 18 15:23:10 2012 +0100

    Free previously allocated memory on errors.

Index: agent/mibgroup/sctp-mib/sctpTables_common.c
===================================================================
--- agent/mibgroup/sctp-mib/sctpTables_common.c.orig
+++ agent/mibgroup/sctp-mib/sctpTables_common.c
@@ -39,6 +39,7 @@ sctpAssocTable_delete_invalid(netsnmp_co
         sctpAssocTable_entry_free(entry);
         CONTAINER_REMOVE(to_delete, NULL);
     }
+    CONTAINER_FREE(to_delete);
 }
 
 static void
@@ -72,6 +73,7 @@ sctpAssocRemAddrTable_delete_invalid(net
         sctpAssocRemAddrTable_entry_free(entry);
         CONTAINER_REMOVE(to_delete, NULL);
     }
+    CONTAINER_FREE(to_delete);
 }
 
 static void
@@ -105,6 +107,7 @@ sctpAssocLocalAddrTable_delete_invalid(n
         sctpAssocLocalAddrTable_entry_free(entry);
         CONTAINER_REMOVE(to_delete, NULL);
     }
+    CONTAINER_FREE(to_delete);
 }
 
 
Index: agent/mibgroup/disman/event/mteTriggerConf.c
===================================================================
--- agent/mibgroup/disman/event/mteTriggerConf.c.orig
+++ agent/mibgroup/disman/event/mteTriggerConf.c
@@ -1474,7 +1474,16 @@ clear_mteTTable(int majorID, int minorID
     netsnmp_tdata_row *row;
 
     while (( row = netsnmp_tdata_row_first( trigger_table_data ))) {
-        netsnmp_tdata_remove_and_delete_row( trigger_table_data, row );
+        struct mteTrigger *entry = (struct mteTrigger *)
+            netsnmp_tdata_remove_and_delete_row(trigger_table_data, row);
+        if (entry) {
+            /* Remove from the callbacks list and disable triggers */
+            snmp_unregister_callback( SNMP_CALLBACK_LIBRARY,
+                                      SNMP_CALLBACK_POST_READ_CONFIG,
+                                      _mteTrigger_callback_enable, entry, 0 );
+            mteTrigger_disable( entry );
+            SNMP_FREE(entry);
+        }
     }
     return SNMPERR_SUCCESS;
 }
Index: agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c
===================================================================
--- agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c.orig
+++ agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c
@@ -290,8 +290,7 @@ udpEndpointTable_container_load(netsnmp_
 
     ITERATOR_RELEASE(ep_it);
 
-    netsnmp_access_udp_endpoint_container_free(ep_c,
-                                               NETSNMP_ACCESS_UDP_ENDPOINT_FREE_DONT_CLEAR);
+    netsnmp_access_udp_endpoint_container_free(ep_c, 0);
 
 
     DEBUGMSGT(("verbose:udpEndpointTable:udpEndpointTable_container_load",
Index: agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
===================================================================
--- agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c.orig
+++ agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
@@ -312,6 +312,7 @@ ipAddressPrefixTable_container_load(nets
         rowreq_ctx = NULL;
         ++count;
     }
+    ITERATOR_RELEASE(addr_it);
 
     DEBUGMSGT(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_container_load", "inserted %d records\n", count));
 
Index: snmplib/snmp_client.c
===================================================================
--- snmplib/snmp_client.c.orig
+++ snmplib/snmp_client.c
@@ -642,8 +642,7 @@ snmp_set_var_objid(netsnmp_variable_list
 {
     size_t          len = sizeof(oid) * name_length;
 
-    if (vp->name != vp->name_loc && vp->name != NULL &&
-        vp->name_length > (sizeof(vp->name_loc) / sizeof(oid))) {
+    if (vp->name != vp->name_loc && vp->name != NULL) {
         /*
          * Probably previously-allocated "big storage".  Better free it
          * else memory leaks possible.  
Index: agent/mibgroup/ucd-snmp/proxy.c
===================================================================
--- agent/mibgroup/ucd-snmp/proxy.c.orig
+++ agent/mibgroup/ucd-snmp/proxy.c
@@ -4,7 +4,7 @@
  */
 /*
  * Portions of this file are copyrighted by:
- * Copyright @ 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright @ 2009 Sun Microsystems, Inc. All rights reserved.
  * Use is subject to license terms specified in the COPYING file
  * distributed with the Net-SNMP package.
  */
@@ -408,6 +408,8 @@ proxy_handler(netsnmp_mib_handler *handl
                 /*
                  * too large 
                  */
+                if (pdu)
+                    snmp_free_pdu(pdu);
                 snmp_log(LOG_ERR,
                          "proxy oid request length is too long\n");
                 return SNMP_ERR_NOERROR;
@@ -437,6 +439,8 @@ proxy_handler(netsnmp_mib_handler *handl
      */
     if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) {
         netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
+        if (pdu)
+            snmp_free_pdu(pdu);
         return SNMP_ERR_NOERROR;
     }
 
Index: agent/helpers/table.c
===================================================================
--- agent/helpers/table.c.orig
+++ agent/helpers/table.c
@@ -837,10 +837,7 @@ netsnmp_table_build_oid_from_index(netsn
     memcpy(&tmpoid[len], table_info->index_oid,
            table_info->index_oid_len * sizeof(oid));
     len += table_info->index_oid_len;
-    if (var->name && var->name != var->name_loc)
-        SNMP_FREE(var->name);
-    snmp_clone_mem((void **) &var->name, tmpoid, len * sizeof(oid));
-    var->name_length = len;
+    snmp_set_var_objid( var, tmpoid, len );
 
     return SNMPERR_SUCCESS;
 }
Index: agent/mibgroup/tcp-mib/tcpConnectionTable/tcpConnectionTable.c
===================================================================
--- agent/mibgroup/tcp-mib/tcpConnectionTable/tcpConnectionTable.c.orig
+++ agent/mibgroup/tcp-mib/tcpConnectionTable/tcpConnectionTable.c
@@ -155,6 +155,8 @@ tcpConnectionTable_rowreq_ctx_cleanup(tc
     /*
      * TODO:211:o: |-> Perform extra tcpConnectionTable rowreq cleanup.
      */
+    netsnmp_access_tcpconn_entry_free(rowreq_ctx->data);
+    rowreq_ctx->data = NULL;
 }                               /* tcpConnectionTable_rowreq_ctx_cleanup */
 
 /**
Index: agent/mibgroup/tcp-mib/tcpListenerTable/tcpListenerTable.c
===================================================================
--- agent/mibgroup/tcp-mib/tcpListenerTable/tcpListenerTable.c.orig
+++ agent/mibgroup/tcp-mib/tcpListenerTable/tcpListenerTable.c
@@ -154,6 +154,8 @@ tcpListenerTable_rowreq_ctx_cleanup(tcpL
     /*
      * TODO:211:o: |-> Perform extra tcpListenerTable rowreq cleanup.
      */
+    netsnmp_access_tcpconn_entry_free(rowreq_ctx->data);
+    rowreq_ctx->data = NULL;
 }                               /* tcpListenerTable_rowreq_ctx_cleanup */
 
 /**
Index: agent/mibgroup/hardware/cpu/cpu_sysctl.c
===================================================================
--- agent/mibgroup/hardware/cpu/cpu_sysctl.c.orig
+++ agent/mibgroup/hardware/cpu/cpu_sysctl.c
@@ -196,6 +196,7 @@ int netsnmp_cpu_arch_load( netsnmp_cache
         cpu = netsnmp_cpu_get_byIdx( i, 0 );
         /* XXX - per-CPU statistics - mcpu_mib[i].??? */
     }
+    free(mcpu_stats);
 #else
         /* Copy "overall" figures to cpu0 entry */
     _cpu_copy_stats( cpu );
Index: agent/mibgroup/host/hr_swinst.c
===================================================================
--- agent/mibgroup/host/hr_swinst.c.orig
+++ agent/mibgroup/host/hr_swinst.c
@@ -477,7 +477,7 @@ var_hrswinst(struct variable * vp,
     case HRSWINST_DATE:
         {
 #ifdef HAVE_LIBRPM
-            int_32         *rpm_data;
+            int         *rpm_data;
             if ( headerGetEntry(swi->swi_h, RPMTAG_INSTALLTIME, NULL, (void **) &rpm_data, NULL) ) {
                 time_t          installTime = *rpm_data;
                 ret = date_n_time(&installTime, var_len);
Index: agent/mibgroup/ip-mib/data_access/systemstats_linux.c
===================================================================
--- agent/mibgroup/ip-mib/data_access/systemstats_linux.c.orig
+++ agent/mibgroup/ip-mib/data_access/systemstats_linux.c
@@ -256,8 +256,13 @@ _systemstats_v4(netsnmp_container* conta
         /*
          * add to container
          */
-        CONTAINER_INSERT(container, entry);
+        if (CONTAINER_INSERT(container, entry) < 0)
+        {
+            DEBUGMSGTL(("access:systemstats:container","error with systemstats_entry: insert into container failed.\n"));
+            netsnmp_access_systemstats_entry_free(entry);
+        }
     }
+
     return 0;
 }
     
@@ -541,7 +546,12 @@ _systemstats_v6_load_systemstats(netsnmp
     /*
      * add to container
      */
-    CONTAINER_INSERT(container, entry);
+        if (CONTAINER_INSERT(container, entry) < 0)
+        {
+            DEBUGMSGTL(("access:systemstats:container","error with systemstats_entry: insert into container failed.\n"));
+            netsnmp_access_systemstats_entry_free(entry);
+        }
+
 
     return rc;
 }
Index: agent/mibgroup/mibII/ipv6.c
===================================================================
--- agent/mibgroup/mibII/ipv6.c.orig
+++ agent/mibgroup/mibII/ipv6.c
@@ -740,6 +740,10 @@ var_ifv6Entry(register struct variable *
     int             max;
     char           *p;
 
+    /* Reload list of interfaces */
+    if (if_initialize() < 0)
+        return NULL;
+
     max = if_maxifindex();
     if (max < 0)
         return NULL;
@@ -1040,6 +1044,10 @@ var_icmpv6Entry(register struct variable
     int             interface;
     int             max;
 
+    /* Reload list of interfaces */
+    if (if_initialize() < 0)
+        return NULL;
+
     max = if_maxifindex();
     if (max < 0)
         return NULL;
@@ -1915,6 +1923,10 @@ var_ifv6Entry(register struct variable *
     struct ifreq    ifr;
     int             s;
 
+    /* Reload list of interfaces */
+    if (if_initialize() < 0)
+        return NULL;
+
     max = if_maxifindex();
     if (max < 0)
         return NULL;
@@ -2060,10 +2072,11 @@ linux_if_freenameindex(struct if_nameind
     int             i;
     if (!ifndx)
         return;
-    for (i = 1; ifndx[i].if_index; i++) {
+    for (i = 0; ifndx[i].if_index; i++) {
         free(ifndx[i].if_name);
     }
     free(ifndx);
+    ifndx = NULL;
 }
 
 #define linux_freeinternalnameindex(ifni, max)  { \
@@ -2084,6 +2097,7 @@ linux_if_nameindex(void)
     struct if_nameindex *ifndx = NULL, *iflist = NULL, *tmp;
     int             i, j;
     int             maxidx, if_count = 0;
+    static int      last_if_count;
 
     f = fopen(LINUX_PROC_NET_IFINET6, "r");
     if (f) {
@@ -2097,10 +2111,11 @@ linux_if_nameindex(void)
                 continue;
             if_name[sizeof(if_name) - 1] = '\0';
             if (maxidx < 0 || maxidx < if_index) {
-
+                if (last_if_count < if_index)
+                    last_if_count = if_index;
                 tmp =
                     realloc(iflist,
-                            (sizeof(struct if_nameindex)) * (if_index +
+                            (sizeof(struct if_nameindex)) * (last_if_count +
                                                              2));
                 if (!tmp) {
                     linux_freeinternalnameindex(iflist, if_index);
Index: snmplib/snmp_api.c
===================================================================
--- snmplib/snmp_api.c.orig
+++ snmplib/snmp_api.c
@@ -986,6 +986,7 @@ _sess_copy(netsnmp_session * in_session)
      * zero out pointers so if we have to free the session we wont free mem
      * owned by in_session 
      */
+    session->localname = NULL;
     session->peername = NULL;
     session->community = NULL;
     session->contextEngineID = NULL;
@@ -1847,6 +1848,7 @@ static void
 snmp_free_session(netsnmp_session * s)
 {
     if (s) {
+        SNMP_FREE(s->localname);
         SNMP_FREE(s->peername);
         SNMP_FREE(s->community);
         SNMP_FREE(s->contextEngineID);
Index: agent/mibgroup/disman/event/mteTrigger.c
===================================================================
--- agent/mibgroup/disman/event/mteTrigger.c.orig
+++ agent/mibgroup/disman/event/mteTrigger.c
@@ -247,6 +247,7 @@ mteTrigger_run( unsigned int reg, void *
         DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n",
                            (( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n));
         _mteTrigger_failure( "failed to run mteTrigger query" );
+        snmp_free_varbind(var);
         return;
     }
 
@@ -291,6 +292,7 @@ mteTrigger_run( unsigned int reg, void *
                 if (!vtmp) {
                     _mteTrigger_failure(
                           "failed to create mteTrigger temp varbind");
+                    snmp_free_varbind(var);
                     return;
                 }
                 vtmp->type = ASN_NULL;
@@ -328,6 +330,7 @@ mteTrigger_run( unsigned int reg, void *
                     if (!vtmp) {
                         _mteTrigger_failure(
                                  "failed to create mteTrigger temp varbind");
+                        snmp_free_varbind(var);
                         return;
                     }
                     vtmp->type = ASN_NULL;
@@ -369,6 +372,7 @@ mteTrigger_run( unsigned int reg, void *
                 if (!vtmp) {
                     _mteTrigger_failure(
                              "failed to create mteTrigger temp varbind");
+                    snmp_free_varbind(var);
                     return;
                 }
                 vtmp->type = ASN_NULL;
@@ -704,6 +708,7 @@ mteTrigger_run( unsigned int reg, void *
                         if (!vtmp) {
                             _mteTrigger_failure(
                                   "failed to create mteTrigger discontinuity varbind");
+                            snmp_free_varbind(dvar);
                             return;
                         }
                         snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID,
