Blame SOURCES/net-snmp-5.8-v3-forward.patch

31d83c
diff -urNp c/agent/snmp_agent.c d/agent/snmp_agent.c
31d83c
--- c/agent/snmp_agent.c	2019-09-18 08:44:53.833601845 +0200
31d83c
+++ d/agent/snmp_agent.c	2019-09-18 08:46:38.176595597 +0200
31d83c
@@ -1604,6 +1604,13 @@ free_agent_snmp_session(netsnmp_agent_se
31d83c
     
31d83c
     DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p freed\n",
31d83c
                 asp, asp->reqinfo));
31d83c
+
31d83c
+    /* Clean up securityStateRef here to prevent a double free */
31d83c
+    if (asp->orig_pdu && asp->orig_pdu->securityStateRef)
31d83c
+	snmp_free_securityStateRef(asp->orig_pdu);
31d83c
+    if (asp->pdu && asp->pdu->securityStateRef)
31d83c
+	snmp_free_securityStateRef(asp->pdu);
31d83c
+
31d83c
     if (asp->orig_pdu)
31d83c
         snmp_free_pdu(asp->orig_pdu);
31d83c
     if (asp->pdu)
31d83c
diff -urNp c/include/net-snmp/pdu_api.h d/include/net-snmp/pdu_api.h
31d83c
--- c/include/net-snmp/pdu_api.h	2019-09-18 08:44:53.822601740 +0200
31d83c
+++ d/include/net-snmp/pdu_api.h	2019-09-18 08:47:03.620838212 +0200
31d83c
@@ -19,6 +19,8 @@ NETSNMP_IMPORT
31d83c
 netsnmp_pdu    *snmp_fix_pdu(  netsnmp_pdu *pdu, int idx);
31d83c
 NETSNMP_IMPORT
31d83c
 void            snmp_free_pdu( netsnmp_pdu *pdu);
31d83c
+NETSNMP_IMPORT
31d83c
+void            snmp_free_securityStateRef( netsnmp_pdu *pdu);
31d83c
 
31d83c
 #ifdef __cplusplus
31d83c
 }
31d83c
diff -urNp c/snmplib/snmp_api.c d/snmplib/snmp_api.c
31d83c
--- c/snmplib/snmp_api.c	2019-09-18 08:44:53.807601597 +0200
31d83c
+++ d/snmplib/snmp_api.c	2019-09-18 08:53:19.937435576 +0200
31d83c
@@ -4012,7 +4012,12 @@ snmpv3_parse(netsnmp_pdu *pdu,
31d83c
 static void
31d83c
 free_securityStateRef(netsnmp_pdu* pdu)
31d83c
 {
31d83c
-    struct snmp_secmod_def *sptr = find_sec_mod(pdu->securityModel);
31d83c
+    struct snmp_secmod_def *sptr;
31d83c
+
31d83c
+    if(!pdu->securityStateRef)
31d83c
+       return;
31d83c
+
31d83c
+    sptr = find_sec_mod(pdu->securityModel);
31d83c
     if (sptr) {
31d83c
         if (sptr->pdu_free_state_ref) {
31d83c
             (*sptr->pdu_free_state_ref) (pdu->securityStateRef);
31d83c
@@ -4029,6 +4034,17 @@ free_securityStateRef(netsnmp_pdu* pdu)
31d83c
     pdu->securityStateRef = NULL;
31d83c
 }
31d83c
 
31d83c
+/*
31d83c
+ * This function is here to provide a separate call to
31d83c
+ * free the securityStateRef memory. This is needed to prevent
31d83c
+ * a double free if this memory is freed in snmp_free_pdu.
31d83c
+ */
31d83c
+void
31d83c
+snmp_free_securityStateRef(netsnmp_pdu* pdu)
31d83c
+{
31d83c
+   free_securityStateRef(pdu);
31d83c
+}
31d83c
+
31d83c
 #define ERROR_STAT_LENGTH 11
31d83c
 
31d83c
 int
31d83c
diff -urNp c/snmplib/snmpusm.c d/snmplib/snmpusm.c
31d83c
--- c/snmplib/snmpusm.c	2019-09-18 08:44:53.802601550 +0200
31d83c
+++ d/snmplib/snmpusm.c	2019-09-18 08:57:35.696872662 +0200
31d83c
@@ -299,16 +299,20 @@ usm_free_usmStateReference(void *old)
31d83c
 
31d83c
     if (old_ref) {
31d83c
 
31d83c
-        SNMP_FREE(old_ref->usr_name);
31d83c
-        SNMP_FREE(old_ref->usr_engine_id);
31d83c
-        SNMP_FREE(old_ref->usr_auth_protocol);
31d83c
-        SNMP_FREE(old_ref->usr_priv_protocol);
31d83c
+        if (old_ref->usr_name_length)
31d83c
+            SNMP_FREE(old_ref->usr_name);
31d83c
+        if (old_ref->usr_engine_id_length)
31d83c
+            SNMP_FREE(old_ref->usr_engine_id);
31d83c
+        if (old_ref->usr_auth_protocol_length)
31d83c
+            SNMP_FREE(old_ref->usr_auth_protocol);
31d83c
+        if (old_ref->usr_priv_protocol_length)
31d83c
+            SNMP_FREE(old_ref->usr_priv_protocol);
31d83c
 
31d83c
-        if (old_ref->usr_auth_key) {
31d83c
+        if (old_ref->usr_auth_key_length && old_ref->usr_auth_key) {
31d83c
             SNMP_ZERO(old_ref->usr_auth_key, old_ref->usr_auth_key_length);
31d83c
             SNMP_FREE(old_ref->usr_auth_key);
31d83c
         }
31d83c
-        if (old_ref->usr_priv_key) {
31d83c
+        if (old_ref->usr_priv_key_length && old_ref->usr_priv_key) {
31d83c
             SNMP_ZERO(old_ref->usr_priv_key, old_ref->usr_priv_key_length);
31d83c
             SNMP_FREE(old_ref->usr_priv_key);
31d83c
         }
31d83c
@@ -1039,7 +1043,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
         if ((user = usm_get_user(secEngineID, secEngineIDLen, secName))
31d83c
             == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) {
31d83c
             DEBUGMSGTL(("usm", "Unknown User(%s)\n", secName));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_UNKNOWNSECURITYNAME;
31d83c
         }
31d83c
 
31d83c
@@ -1091,7 +1094,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
                                         thePrivProtocolLength) == 1) {
31d83c
         DEBUGMSGTL(("usm", "Unsupported Security Level (%d)\n",
31d83c
                     theSecLevel));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL;
31d83c
     }
31d83c
 
31d83c
@@ -1121,7 +1123,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
                          &msgAuthParmLen, &msgPrivParmLen, &otstlen,
31d83c
                          &seq_len, &msgSecParmLen) == -1) {
31d83c
         DEBUGMSGTL(("usm", "Failed calculating offsets.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_USM_GENERICERROR;
31d83c
     }
31d83c
 
31d83c
@@ -1143,7 +1144,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
     ptr = *wholeMsg = globalData;
31d83c
     if (theTotalLength > *wholeMsgLen) {
31d83c
         DEBUGMSGTL(("usm", "Message won't fit in buffer.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_USM_GENERICERROR;
31d83c
     }
31d83c
 
31d83c
@@ -1169,7 +1169,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
                                htonl(boots_uint), htonl(time_uint),
31d83c
                                &ptr[privParamsOffset]) == -1) {
31d83c
                 DEBUGMSGTL(("usm", "Can't set AES iv.\n"));
31d83c
-                usm_free_usmStateReference(secStateRef);
31d83c
                 return SNMPERR_USM_GENERICERROR;
31d83c
             }
31d83c
         }
31d83c
@@ -1185,7 +1184,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
                               &ptr[privParamsOffset])
31d83c
                  == -1)) {
31d83c
                 DEBUGMSGTL(("usm", "Can't set DES-CBC salt.\n"));
31d83c
-                usm_free_usmStateReference(secStateRef);
31d83c
                 return SNMPERR_USM_GENERICERROR;
31d83c
             }
31d83c
         }
31d83c
@@ -1198,7 +1196,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
                        &ptr[dataOffset], &encrypted_length)
31d83c
             != SNMP_ERR_NOERROR) {
31d83c
             DEBUGMSGTL(("usm", "encryption error.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_ENCRYPTIONERROR;
31d83c
         }
31d83c
 #ifdef NETSNMP_ENABLE_TESTING_CODE
31d83c
@@ -1226,7 +1223,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
         if ((encrypted_length != (theTotalLength - dataOffset))
31d83c
             || (salt_length != msgPrivParmLen)) {
31d83c
             DEBUGMSGTL(("usm", "encryption length error.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_ENCRYPTIONERROR;
31d83c
         }
31d83c
 
31d83c
@@ -1362,7 +1358,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
 
31d83c
         if (temp_sig == NULL) {
31d83c
             DEBUGMSGTL(("usm", "Out of memory.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_GENERICERROR;
31d83c
         }
31d83c
 
31d83c
@@ -1376,7 +1371,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
             SNMP_ZERO(temp_sig, temp_sig_len);
31d83c
             SNMP_FREE(temp_sig);
31d83c
             DEBUGMSGTL(("usm", "Signing failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_AUTHENTICATIONFAILURE;
31d83c
         }
31d83c
 
31d83c
@@ -1384,7 +1378,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
             SNMP_ZERO(temp_sig, temp_sig_len);
31d83c
             SNMP_FREE(temp_sig);
31d83c
             DEBUGMSGTL(("usm", "Signing lengths failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_AUTHENTICATIONFAILURE;
31d83c
         }
31d83c
 
31d83c
@@ -1398,7 +1391,6 @@ usm_generate_out_msg(int msgProcModel,
31d83c
     /*
31d83c
      * endif -- create keyed hash 
31d83c
      */
31d83c
-    usm_free_usmStateReference(secStateRef);
31d83c
 
31d83c
     DEBUGMSGTL(("usm", "USM processing completed.\n"));
31d83c
 
31d83c
@@ -1548,7 +1540,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
         if ((user = usm_get_user(secEngineID, secEngineIDLen, secName))
31d83c
             == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) {
31d83c
             DEBUGMSGTL(("usm", "Unknown User\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_UNKNOWNSECURITYNAME;
31d83c
         }
31d83c
 
31d83c
@@ -1601,7 +1592,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
         DEBUGMSGTL(("usm", "Unsupported Security Level or type (%d)\n",
31d83c
                     theSecLevel));
31d83c
 
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL;
31d83c
     }
31d83c
 
31d83c
@@ -1636,7 +1626,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
             DEBUGMSGTL(("usm",
31d83c
                         "couldn't malloc %d bytes for encrypted PDU\n",
31d83c
                         (int)ciphertextlen));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_MALLOC;
31d83c
         }
31d83c
 
31d83c
@@ -1652,7 +1641,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                                htonl(boots_uint), htonl(time_uint),
31d83c
                                iv) == -1) {
31d83c
                 DEBUGMSGTL(("usm", "Can't set AES iv.\n"));
31d83c
-                usm_free_usmStateReference(secStateRef);
31d83c
                 SNMP_FREE(ciphertext);
31d83c
                 return SNMPERR_USM_GENERICERROR;
31d83c
             }
31d83c
@@ -1667,7 +1655,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                                              thePrivKeyLength - 8,
31d83c
                                              iv) == -1)) {
31d83c
                 DEBUGMSGTL(("usm", "Can't set DES-CBC salt.\n"));
31d83c
-                usm_free_usmStateReference(secStateRef);
31d83c
                 SNMP_FREE(ciphertext);
31d83c
                 return SNMPERR_USM_GENERICERROR;
31d83c
             }
31d83c
@@ -1686,7 +1673,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                        scopedPdu, scopedPduLen,
31d83c
                        ciphertext, &ciphertextlen) != SNMP_ERR_NOERROR) {
31d83c
             DEBUGMSGTL(("usm", "encryption error.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             SNMP_FREE(ciphertext);
31d83c
             return SNMPERR_USM_ENCRYPTIONERROR;
31d83c
         }
31d83c
@@ -1703,7 +1689,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                                        ciphertext, ciphertextlen);
31d83c
         if (rc == 0) {
31d83c
             DEBUGMSGTL(("usm", "Encryption failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             SNMP_FREE(ciphertext);
31d83c
             return SNMPERR_USM_ENCRYPTIONERROR;
31d83c
         }
31d83c
@@ -1743,7 +1728,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     DEBUGINDENTLESS();
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building privParams failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1766,7 +1750,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     DEBUGINDENTLESS();
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building authParams failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1789,7 +1772,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     DEBUGINDENTLESS();
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building authParams failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1805,7 +1787,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm",
31d83c
                     "building msgAuthoritativeEngineTime failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1821,7 +1802,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm",
31d83c
                     "building msgAuthoritativeEngineBoots failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1833,7 +1813,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     DEBUGINDENTLESS();
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building msgAuthoritativeEngineID failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1846,7 +1825,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                                      *offset - sp_offset);
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building usm security parameters failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1860,7 +1838,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
 
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building msgSecurityParameters failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1870,7 +1847,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     while ((*wholeMsgLen - *offset) < globalDataLen) {
31d83c
         if (!asn_realloc(wholeMsg, wholeMsgLen)) {
31d83c
             DEBUGMSGTL(("usm", "building global data failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_TOO_LONG;
31d83c
         }
31d83c
     }
31d83c
@@ -1886,7 +1862,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
                                                ASN_CONSTRUCTOR), *offset);
31d83c
     if (rc == 0) {
31d83c
         DEBUGMSGTL(("usm", "building master packet sequence failed.\n"));
31d83c
-        usm_free_usmStateReference(secStateRef);
31d83c
         return SNMPERR_TOO_LONG;
31d83c
     }
31d83c
 
31d83c
@@ -1904,7 +1879,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
 
31d83c
         if (temp_sig == NULL) {
31d83c
             DEBUGMSGTL(("usm", "Out of memory.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_GENERICERROR;
31d83c
         }
31d83c
 
31d83c
@@ -1915,14 +1889,12 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
             != SNMP_ERR_NOERROR) {
31d83c
             SNMP_FREE(temp_sig);
31d83c
             DEBUGMSGTL(("usm", "Signing failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_AUTHENTICATIONFAILURE;
31d83c
         }
31d83c
 
31d83c
         if (temp_sig_len != msgAuthParmLen) {
31d83c
             SNMP_FREE(temp_sig);
31d83c
             DEBUGMSGTL(("usm", "Signing lengths failed.\n"));
31d83c
-            usm_free_usmStateReference(secStateRef);
31d83c
             return SNMPERR_USM_AUTHENTICATIONFAILURE;
31d83c
         }
31d83c
 
31d83c
@@ -1933,7 +1905,6 @@ usm_rgenerate_out_msg(int msgProcModel,
31d83c
     /*
31d83c
      * endif -- create keyed hash 
31d83c
      */
31d83c
-    usm_free_usmStateReference(secStateRef);
31d83c
     DEBUGMSGTL(("usm", "USM processing completed.\n"));
31d83c
     return SNMPERR_SUCCESS;
31d83c
 }                               /* end usm_rgenerate_out_msg() */