From 87bd90d04f20dd3f73e3e7e631a442ccd419b9d3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 13 Aug 2019 20:54:23 -0700 Subject: [PATCH] libsnmp: Move the free_securityStateRef() call into snmp_free_pdu() This patch fixes a memory leak that was introduced in commit 5f881d3bf245 ("libsnmp, USM: Introduce a reference count in struct usmStateReference"). This patch partially reverts commit adc9b71aba91 ("snmpd: Avoid that snmpv3 bulkget errors result in a double free"). See also https://sourceforge.net/p/net-snmp/bugs/2938/. --- agent/snmp_agent.c| 6 ------ include/net-snmp/pdu_api.h | 2 -- snmplib/snmp_api.c| 23 ++--------------------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c index 0a1e263..25350e6 100644 --- a/agent/snmp_agent.c +++ b/agent/snmp_agent.c @@ -1605,12 +1605,6 @@ free_agent_snmp_session(netsnmp_agent_session *asp) DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p freed\n", asp, asp->reqinfo)); - /* Clean up securityStateRef here to prevent a double free */ - if (asp->orig_pdu) - snmp_free_securityStateRef(asp->orig_pdu); - if (asp->pdu) - snmp_free_securityStateRef(asp->pdu); - if (asp->orig_pdu) snmp_free_pdu(asp->orig_pdu); if (asp->pdu) diff --git a/include/net-snmp/pdu_api.h b/include/net-snmp/pdu_api.h index 270aff0..125595d 100644 --- a/include/net-snmp/pdu_api.h +++ b/include/net-snmp/pdu_api.h @@ -19,8 +19,6 @@ NETSNMP_IMPORT netsnmp_pdu *snmp_fix_pdu( netsnmp_pdu *pdu, int idx); NETSNMP_IMPORT void snmp_free_pdu( netsnmp_pdu *pdu); -NETSNMP_IMPORT -void snmp_free_securityStateRef( netsnmp_pdu *pdu); #ifdef __cplusplus } diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c index e14ae6f..3e57a55 100644 --- a/snmplib/snmp_api.c +++ b/snmplib/snmp_api.c @@ -4033,17 +4033,6 @@ free_securityStateRef(netsnmp_pdu* pdu) pdu->securityStateRef = NULL; } -/* - * This function is here to provide a separate call to - * free the securityStateRef memory. This is needed to prevent - * a double free if this memory is freed in snmp_free_pdu. - */ -void -snmp_free_securityStateRef(netsnmp_pdu* pdu) -{ - free_securityStateRef(pdu); -} - #define ERROR_STAT_LENGTH 11 int @@ -5470,6 +5459,8 @@ snmp_free_pdu(netsnmp_pdu *pdu) if (!pdu) return; + free_securityStateRef(pdu); + /* * If the command field is empty, that probably indicates * that this PDU structure has already been freed. @@ -5644,10 +5635,6 @@ _sess_process_packet_parse_pdu(void *sessp, netsnmp_session * sp, } if (ret != SNMP_ERR_NOERROR) { - /* - * Call the security model to free any securityStateRef supplied w/ msg. - */ - free_securityStateRef(pdu); snmp_free_pdu(pdu); return NULL; } @@ -5819,12 +5806,6 @@ _sess_process_packet_handle_pdu(void *sessp, netsnmp_session * sp, } } - /* - * Call USM to free any securityStateRef supplied with the message. - */ - if (pdu->command == SNMP_MSG_TRAP2) - free_securityStateRef(pdu); - if (!handled) { if (sp->flags & SNMP_FLAGS_SHARED_SOCKET) return -2; -- 1.8.3.1