From: Wes Hardaker
Subject: Misc fixes for freeing memory during error conditions.
References: bnc#695786
Patch-upstream: r17543

Signed-off-by: Leonardo Chiquitto <lchiquitto@suse.de>

---
 apps/encode_keychange.c             |    5 ++
 snmplib/keytools.c                  |    3 +
 snmplib/snmpUDPIPv6Domain.c         |   72 +++++++++++++++++++-----------------
 snmplib/container_binary_array.c    |    3 +
 snmplib/mib.c                       |   27 +++++++------
 snmplib/parse.c                     |    3 +
 snmplib/snmpv3.c                    |    1 
 agent/mibgroup/mibII/ipv6.c         |   12 +++---
 agent/mibgroup/mibII/vacm_context.c |    1 
 agent/helpers/table_data.c          |    8 +++-
 agent/helpers/table_dataset.c       |    7 +++
 11 files changed, 86 insertions(+), 56 deletions(-)

Index: apps/encode_keychange.c
===================================================================
--- apps/encode_keychange.c.orig
+++ apps/encode_keychange.c
@@ -478,7 +478,7 @@ get_user_passphrases(void)
     char            path[SNMP_MAXBUF], buf[SNMP_MAXBUF], *s = NULL;
 
     struct stat     statbuf;
-    FILE           *fp;
+    FILE           *fp = NULL;
 
 
 
@@ -624,6 +624,9 @@ get_user_passphrases(void)
         SNMP_FREE(nbuf);
     }
 
+    if (fp)
+        fclose (fp);
+
     return rval;
 
 }                               /* end get_user_passphrases() */
Index: snmplib/keytools.c
===================================================================
--- snmplib/keytools.c.orig
+++ snmplib/keytools.c
@@ -401,6 +401,9 @@ encode_keychange(const oid * hashtype, u
     /*
      * Sanity check.
      */
+    if (!kcstring || !kcstring_len)
+	return SNMPERR_GENERR;
+
     if (!hashtype || !oldkey || !newkey || !kcstring || !kcstring_len
         || (oldkey_len <= 0) || (newkey_len <= 0) || (*kcstring_len <= 0)
         || (hashtype_len != USM_LENGTH_OID_TRANSFORM)) {
Index: snmplib/snmpUDPIPv6Domain.c
===================================================================
--- snmplib/snmpUDPIPv6Domain.c.orig
+++ snmplib/snmpUDPIPv6Domain.c
@@ -690,7 +690,11 @@ inet_make_mask_addr(int pf, void *dst, i
             mask |= maskbit;
             maskbit >>= 1;
         }
-        (*(u_char *) (&((struct in6_addr *) dst)->s6_addr[j])) = mask;
+
+	if (j < sizeof (((struct in6_addr *) dst)->s6_addr)){
+	    (*(u_char *) (&((struct in6_addr *) dst)->s6_addr[j])) = mask;
+	}
+
         break;
     default:
         return -1;              /* unsupported protocol family */
@@ -1066,39 +1070,39 @@ netsnmp_udp6_parse_security(const char *
      * Deal with the network part first.  
      */
     if ((strcmp(source, "default") == 0) || (strcmp(source, "::") == 0)) {
-        strnetwork = strdup("0::0");
-        strmask = strdup("0::0");
-
-        inet_pton(AF_INET6, strnetwork, &net.sin6_addr);
-        inet_pton(AF_INET6, strmask, &mask.sin6_addr);
-
-        e = (com2Sec6Entry *) malloc(sizeof(com2Sec6Entry));
-        if (e == NULL) {
-            config_perror("memory error");
-            return;
-        }
-        /*
-         * Everything is okay.  Copy the parameters to the structure allocated
-         * above and add it to END of the list.  
-         */
-        if (strmask != NULL && strnetwork != NULL) {
-            DEBUGMSGTL(("netsnmp_udp6_parse_security",
-                        "<\"%s\", %s/%s> => \"%s\"\n", community,
-                        strnetwork, strmask, secName));
-            free(strmask);
-            free(strnetwork);
-        } else {
-            DEBUGMSGTL(("netsnmp_udp6_parse_security",
-                        "Couldn't allocate enough memory\n"));
-        }
-        memmove_com2Sec6Entry(e, secName, community, net, mask, contextName);
-        if (com2Sec6ListLast != NULL) {
-            com2Sec6ListLast->next = e;
-            com2Sec6ListLast = e;
-        } else {
-            com2Sec6ListLast = com2Sec6List = e;
-        }
-
+        if ((strnetwork = strdup("0::0")) != NULL)
+	{
+	    if ((strmask = strdup("0::0")) != NULL)
+	    {
+
+		inet_pton(AF_INET6, strnetwork, &net.sin6_addr);
+		inet_pton(AF_INET6, strmask, &mask.sin6_addr);
+
+		e = (com2Sec6Entry *) malloc(sizeof(com2Sec6Entry));
+		if (e != NULL) {
+		    memmove_com2Sec6Entry(e, secName, community, net, mask, contextName);
+		    if (com2Sec6ListLast != NULL) {
+			com2Sec6ListLast->next = e;
+			com2Sec6ListLast = e;
+		    } else {
+			com2Sec6ListLast = com2Sec6List = e;
+		    }
+		}
+		else {
+		    config_perror ("memory error");
+		}
+		free (strmask);
+	    }
+	    else {
+		DEBUGMSGTL(("netsnmp_udp6_parse_security",
+			    "Couldn't allocate enough memory\n"));
+	    }
+	    free (strnetwork);
+	}
+	else {
+	    DEBUGMSGTL(("netsnmp_udp6_parse_security",
+			"Couldn't allocate enough memory\n"));
+	}
     } else {
         /*
          * Try interpreting as IPv6 address.  
Index: snmplib/container_binary_array.c
===================================================================
--- snmplib/container_binary_array.c.orig
+++ snmplib/container_binary_array.c
@@ -531,7 +531,10 @@ _ba_get_subset(netsnmp_container *contai
     
     va = SNMP_MALLOC_TYPEDEF(netsnmp_void_array);
     if (NULL==va)
+    {
+        free (rtn);
         return NULL;
+    }
 
     va->size = len;
     va->array = rtn;
Index: snmplib/mib.c
===================================================================
--- snmplib/mib.c.orig
+++ snmplib/mib.c
@@ -2109,9 +2109,10 @@ handle_print_numeric(const char *token,
     char       *st;
 
     value = strtok_r(line, " \t\n", &st);
-    if ((strcasecmp(value, "yes")  == 0) || 
-	(strcasecmp(value, "true") == 0) ||
-	(*value == '1')) {
+    if (value && (
+	    (strcasecmp(value, "yes")  == 0) ||
+	    (strcasecmp(value, "true") == 0) ||
+	    (*value == '1') )) {
 
         netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
                                                   NETSNMP_OID_OUTPUT_NUMERIC);
@@ -3366,17 +3367,19 @@ sprint_realloc_value(u_char ** buf, size
                                             NETSNMP_DS_LIB_DONT_PRINT_UNITS)) {
             units = subtree->units;
         }
-        if (subtree && subtree->printomat) {
+        if (subtree) {
+	    if(subtree->printomat) {
             return (*subtree->printomat) (buf, buf_len, out_len,
                                           allow_realloc, variable,
                                           subtree->enums, subtree->hint,
                                           units);
-        } else {
-            return sprint_realloc_by_type(buf, buf_len, out_len,
-                                          allow_realloc, variable,
-                                          subtree->enums, subtree->hint,
-                                          units);
-        }
+	    } else {
+		return sprint_realloc_by_type(buf, buf_len, out_len,
+					      allow_realloc, variable,
+					      subtree->enums, subtree->hint,
+					      units);
+	    }
+	}
 #else
         return sprint_realloc_by_type(buf, buf_len, out_len,
                                       allow_realloc, variable,
@@ -5406,14 +5409,14 @@ _add_strings_to_oid(void *tp, char *cp,
                 (*objidlen)++;
             }
 
+            if (!cp)
+                goto bad_id;
             while (*cp && *cp != doingquote) {
                 if (*objidlen >= maxlen)
                     goto bad_id;
                 objid[*objidlen] = *cp++;
                 (*objidlen)++;
             }
-            if (!cp)
-                goto bad_id;
             cp2 = cp + 1;
             if (!*cp2)
                 cp2 = NULL;
Index: snmplib/parse.c
===================================================================
--- snmplib/parse.c.orig
+++ snmplib/parse.c
@@ -2952,6 +2952,9 @@ eat_syntax(FILE * fp, char *token, int m
     struct node    *np = alloc_node(current_module);
     char            nexttoken[MAXTOKEN];
 
+    if (!np)
+	return 0;
+
     type = get_token(fp, token, maxtoken);
     nexttype = get_token(fp, nexttoken, MAXTOKEN);
     switch (type) {
Index: snmplib/snmpv3.c
===================================================================
--- snmplib/snmpv3.c.orig
+++ snmplib/snmpv3.c
@@ -882,6 +882,7 @@ usm_parse_create_usmUser(const char *tok
                                newuser->authProtocolLen);
     if (ret2 <= 0) {
         config_perror("Could not get proper authentication protocol key length");
+	usm_free_user(newuser);
         return;
     }
     newuser->authKey = (u_char *) malloc(ret2);
Index: agent/mibgroup/mibII/ipv6.c
===================================================================
--- agent/mibgroup/mibII/ipv6.c.orig
+++ agent/mibgroup/mibII/ipv6.c
@@ -778,7 +778,7 @@ var_ifv6Entry(register struct variable *
             memset(&ifr, 0, sizeof(ifr));
             ifr.ifr_addr.sa_family = AF_INET6;
             strncpy(ifr.ifr_name, if_getname(interface),
-                    sizeof(ifr.ifr_name));
+                    sizeof(ifr.ifr_name) - 1);
             if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFMTU, (caddr_t) & ifr) < 0) {
@@ -945,7 +945,7 @@ var_ifv6Entry(register struct variable *
 
             memset(&ifr, 0, sizeof(ifr));
             strncpy(ifr.ifr_name, if_getname(interface),
-                    sizeof(ifr.ifr_name));
+                    sizeof(ifr.ifr_name) - 1);
             if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFSTAT_IN6, (caddr_t) & ifr) < 0) {
@@ -1098,7 +1098,7 @@ var_icmpv6Entry(register struct variable
 
             memset(&ifr, 0, sizeof(ifr));
             strncpy(ifr.ifr_name, if_getname(interface),
-                    sizeof(ifr.ifr_name));
+                    sizeof(ifr.ifr_name) - 1);
             if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFSTAT_ICMP6, (caddr_t) & ifr) < 0) {
@@ -1951,7 +1951,7 @@ var_ifv6Entry(register struct variable *
                 break;
             memset(&ifr, 0, sizeof(ifr));
             ifr.ifr_addr.sa_family = AF_INET6;
-            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
             if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFMTU, (caddr_t) & ifr) < 0) {
@@ -1971,7 +1971,7 @@ var_ifv6Entry(register struct variable *
                 break;
             memset(&ifr, 0, sizeof(ifr));
             ifr.ifr_addr.sa_family = AF_INET6;
-            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
             if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
@@ -2000,7 +2000,7 @@ var_ifv6Entry(register struct variable *
                 break;
             memset(&ifr, 0, sizeof(ifr));
             ifr.ifr_addr.sa_family = AF_INET6;
-            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+            strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
             if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                 break;
             if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
Index: agent/mibgroup/mibII/vacm_context.c
===================================================================
--- agent/mibgroup/mibII/vacm_context.c.orig
+++ agent/mibgroup/mibII/vacm_context.c
@@ -95,6 +95,7 @@ init_vacm_context(void)
     if (!table_info || !iinfo) {
         SNMP_FREE(table_info);
         SNMP_FREE(iinfo);
+        SNMP_FREE(my_handler);
         return;
     }
 
Index: agent/helpers/table_data.c
===================================================================
--- agent/helpers/table_data.c.orig
+++ agent/helpers/table_data.c
@@ -80,16 +80,20 @@ netsnmp_table_data_clone_row(netsnmp_tab
 
     if (row->indexes) {
         newrow->indexes = snmp_clone_varbind(newrow->indexes);
-        if (!newrow->indexes)
+        if (!newrow->indexes) {
+            free (newrow);
             return NULL;
+        }
     }
 
     if (row->index_oid) {
         memdup((u_char **) & newrow->index_oid,
                (u_char *) row->index_oid,
                row->index_oid_len * sizeof(oid));
-        if (!newrow->index_oid)
+        if (!newrow->index_oid) {
+            free (newrow);
             return NULL;
+        }
     }
 
     return newrow;
Index: agent/helpers/table_dataset.c
===================================================================
--- agent/helpers/table_dataset.c.orig
+++ agent/helpers/table_dataset.c
@@ -563,7 +563,7 @@ netsnmp_table_data_set_helper_handler(ne
             data = (netsnmp_table_data_set_storage *) row->data;
 
         if (!row || !table_info || !data) {
-            if (!MODE_IS_SET(reqinfo->mode)) {
+            if (!MODE_IS_SET(reqinfo->mode) || !table_info) {
                 netsnmp_set_request_error(reqinfo, request,
                                           SNMP_NOSUCHINSTANCE);
                 continue;
@@ -993,6 +993,7 @@ netsnmp_config_parse_table_set(const cha
         if (!snmp_parse_oid(tp->augments, name, &name_length)) {
             config_pwarn("I can't parse the augment tabel name");
             snmp_log(LOG_WARNING, "  can't parse %s\n", tp->augments);
+            SNMP_FREE (table_set);
             return;
         }
         if(NULL == (tp2 = get_tree(name, name_length, get_tree_head()))) {
@@ -1000,6 +1001,7 @@ netsnmp_config_parse_table_set(const cha
                          "I can't find mib information about augment table");
             snmp_log(LOG_WARNING, "  table %s not found in tree\n",
                      tp->augments);
+            SNMP_FREE (table_set);
             return;
         }
         _table_set_add_indexes(table_set, tp2);
@@ -1016,6 +1018,7 @@ netsnmp_config_parse_table_set(const cha
         type = mib_to_asn_type(tp->type);
         if (type == (u_char) - 1) {
             config_pwarn("unknown column type");
+	    SNMP_FREE (table_set);
             return;             /* xxx mem leak */
         }
 
@@ -1091,6 +1094,7 @@ netsnmp_config_parse_add_row(const char
          vb = vb->next_variable) {
         if (!line) {
             config_pwarn("missing an index value");
+            SNMP_FREE (row);
             return;
         }
 
@@ -1110,6 +1114,7 @@ netsnmp_config_parse_add_row(const char
                          "All columns must be specified.");
             snmp_log(LOG_WARNING,"  can't find value for column %d\n",
                      dr->column - 1);
+            SNMP_FREE (row);
             return;
         }
 
