Menu

#2503 Memory leak in inetCidrRouteTable and ipCidrRouteTable

linux
closed
None
5
2016-04-27
2013-10-23
No

I have found a memory leak in both inetCidrRouteTable and ipCidrRouteTable:

  • net-snmp 5.7.2
  • embedded linux, ARM architecture

How to reproduce:

  • enable ip-forward-mib
  • start snmpd
  • retrieve the tables
  • shutdown snmpd

Valgrind reports:

==1034== 32 (16 direct, 16 indirect) bytes in 2 blocks are definitely lost in loss record 42 of 107
==1034== at 0x401115C: calloc (in /lib.debug/valgrind/vgpreload_memcheck-x86-linux.so)
==1034== by 0x4147A81: _ssll_insert (container_list_ssll.c:147)
==1034== by 0x4145A4B: CONTAINER_INSERT_HELPER (container.c:326)
==1034== by 0x4145A7F: CONTAINER_INSERT (container.c:349)
==1034== by 0x409280B: _load_ipv4 (route_linux.c:185)
==1034== by 0x4092B15: netsnmp_access_route_container_arch_load (route_linux.c:363)
==1034== by 0x40922FE: netsnmp_access_route_container_load (route_common.c:60)
==1034== by 0x40829AD: ipCidrRouteTable_container_load (ipCidrRouteTable_data_access.c:250)
==1034== by 0x4081D1C: _cache_load (ipCidrRouteTable_interface.c:2196)
==1034== by 0x402BBA1: _cache_load (cache_handler.c:700)
==1034== by 0x402C42C: netsnmp_cache_helper_handler (cache_handler.c:638)
==1034== by 0x40364EA: netsnmp_call_handler (agent_handler.c:526)

==1034== 376 (48 direct, 328 indirect) bytes in 6 blocks are definitely lost in loss record 91 of 107
==1034== at 0x401115C: calloc (in /lib.debug/valgrind/vgpreload_memcheck-x86-linux.so)
==1034== by 0x4147A81: _ssll_insert (container_list_ssll.c:147)
==1034== by 0x4145A4B: CONTAINER_INSERT_HELPER (container.c:326)
==1034== by 0x4145A7F: CONTAINER_INSERT (container.c:349)
==1034== by 0x409280B: _load_ipv4 (route_linux.c:185)
==1034== by 0x4092B15: netsnmp_access_route_container_arch_load (route_linux.c:363)
==1034== by 0x40922FE: netsnmp_access_route_container_load (route_common.c:60)
==1034== by 0x408441B: inetCidrRouteTable_container_load (inetCidrRouteTable_data_access.c:262)
==1034== by 0x40834AB: _cache_load (inetCidrRouteTable_interface.c:2242)
==1034== by 0x402BBA1: _cache_load (cache_handler.c:700)
==1034== by 0x402C42C: netsnmp_cache_helper_handler (cache_handler.c:638)
==1034== by 0x40364EA: netsnmp_call_handler (agent_handler.c:526)

The issue is caused by the unusual handling of the container/cache:

  1. ipCidrRouteTable_data_access.c: ipCidrRouteTable_container_load()

    • loads the routing data into a container route_container
    • iterates over the data with CONTAINER_FOR_EACH and calls _snarf_route_entry
    • _snarf_route_entry either frees the data of the entry or stores that data otherwise
    • netsnmp_access_route_container_free(route_container, NETSNMP_ACCESS_ROUTE_FREE_DONT_CLEAR) is called
  2. route_common.c: netsnmp_access_route_container_free()

    • does not call CONTAINER_CLEAR() since the DONT_CLEAR flag is set
    • frees the container itself (but not the entries)

When the actual routing data was added to the container via CONTAINER_INSERT (in route_linux.c), this kind of container which is used for the ip-forward-mib ("access:_route:fifo" / container_list_ssll.c) will actually allocate a helper data structure (sl_node) for each entry.

Since that sl_node is neither freed nor transferred to a new owner in _snarf_route_entry (only the actual data is freed/transferred), these sl_node data structures will never be freed.

A possible solution could be to call CONTAINER_CLEAR even if the DONT_CLEAR flag is set, but don't provide a cleanup function:

That will free the sl_nodes, but won't touch the actual data (which is already taken care of).

--- net-snmp/agent/mibgroup/ip-forward-mib/data_access/route_common.c   2013/10/23 15:37:58 226468
+++ net-snmp/agent/mibgroup/ip-forward-mib/data_access/route_common.c   2013/10/23 15:42:56 226469
@@ -83,6 +83,12 @@
         CONTAINER_CLEAR(container,
                         (netsnmp_container_obj_func*)_access_route_entry_release,
                         NULL);
+    } else {
+   /*
+    * free the CONTAINER's sl_nodes, but not their data
+    */
+   CONTAINER_CLEAR(container, NULL, NULL); 
     }

     if(! (free_flags & NETSNMP_ACCESS_ROUTE_FREE_KEEP_CONTAINER))

Discussion

  • Sam Tannous

    Sam Tannous - 2016-04-21

    Hi Christian,

    I can confirm that your suggested patch works. You should submit this as a working patch.

    Regards,
    Sam Tannous

     
  • Sam Tannous

    Sam Tannous - 2016-04-22
     
  • Niels Baggesen

    Niels Baggesen - 2016-04-27
    • status: open --> closed
    • assigned_to: Niels Baggesen
     
  • Niels Baggesen

    Niels Baggesen - 2016-04-27

    Thanks for the patch, and sorry for the delay in fixing this :-(
    The fix has been applied to all active branches.

     
  • Christian Krause

    Ok, perfect - thanks! Is there a plan for a 5.7.4 release in the near future?

     

Log in to post a comment.