]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: fix iptable memleak, fix free funcs
authorQuentin Young <qlyoung@cumulusnetworks.com>
Sat, 4 Jan 2020 03:28:53 +0000 (22:28 -0500)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 15 Jan 2020 17:49:51 +0000 (12:49 -0500)
- Fix iptable freeing code to free malloc'd list
- malloc iptable in zapi handler and use those functions to free it when
  done to fix a linked list memleak

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
zebra/zapi_msg.c
zebra/zebra_pbr.c

index 1c5182c5d824a3c09baa5890a93be8d27c188498..4950b8654d55724dc638348b051430630e51d4c4 100644 (file)
@@ -2403,37 +2403,39 @@ stream_failure:
 
 static inline void zread_iptable(ZAPI_HANDLER_ARGS)
 {
-       struct zebra_pbr_iptable zpi;
+       struct zebra_pbr_iptable *zpi =
+               XCALLOC(MTYPE_TMP, sizeof(struct zebra_pbr_iptable));
        struct stream *s;
 
        s = msg;
 
-       memset(&zpi, 0, sizeof(zpi));
-
-       zpi.interface_name_list = list_new();
-       zpi.sock = client->sock;
-       zpi.vrf_id = zvrf->vrf->vrf_id;
-       STREAM_GETL(s, zpi.unique);
-       STREAM_GETL(s, zpi.type);
-       STREAM_GETL(s, zpi.filter_bm);
-       STREAM_GETL(s, zpi.action);
-       STREAM_GETL(s, zpi.fwmark);
-       STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
-       STREAM_GETW(s, zpi.pkt_len_min);
-       STREAM_GETW(s, zpi.pkt_len_max);
-       STREAM_GETW(s, zpi.tcp_flags);
-       STREAM_GETW(s, zpi.tcp_mask_flags);
-       STREAM_GETC(s, zpi.dscp_value);
-       STREAM_GETC(s, zpi.fragment);
-       STREAM_GETC(s, zpi.protocol);
-       STREAM_GETL(s, zpi.nb_interface);
-       zebra_pbr_iptable_update_interfacelist(s, &zpi);
+       zpi->interface_name_list = list_new();
+       zpi->sock = client->sock;
+       zpi->vrf_id = zvrf->vrf->vrf_id;
+       STREAM_GETL(s, zpi->unique);
+       STREAM_GETL(s, zpi->type);
+       STREAM_GETL(s, zpi->filter_bm);
+       STREAM_GETL(s, zpi->action);
+       STREAM_GETL(s, zpi->fwmark);
+       STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
+       STREAM_GETW(s, zpi->pkt_len_min);
+       STREAM_GETW(s, zpi->pkt_len_max);
+       STREAM_GETW(s, zpi->tcp_flags);
+       STREAM_GETW(s, zpi->tcp_mask_flags);
+       STREAM_GETC(s, zpi->dscp_value);
+       STREAM_GETC(s, zpi->fragment);
+       STREAM_GETC(s, zpi->protocol);
+       STREAM_GETL(s, zpi->nb_interface);
+       zebra_pbr_iptable_update_interfacelist(s, zpi);
 
        if (hdr->command == ZEBRA_IPTABLE_ADD)
-               zebra_pbr_add_iptable(&zpi);
+               zebra_pbr_add_iptable(zpi);
        else
-               zebra_pbr_del_iptable(&zpi);
+               zebra_pbr_del_iptable(zpi);
+
 stream_failure:
+       zebra_pbr_iptable_free(zpi);
+       zpi = NULL;
        return;
 }
 
index f95a4ff950e72738ed3ecc254940ca4a76896417..cd620b5ffa4872ac0a5b034ceef8b1207dafd855 100644 (file)
@@ -350,11 +350,13 @@ void zebra_pbr_iptable_free(void *arg)
        iptable = (struct zebra_pbr_iptable *)arg;
        hook_call(zebra_pbr_iptable_update, 0, iptable);
 
-       for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
-                                       node, nnode, name)) {
-               XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
-               list_delete_node(iptable->interface_name_list,
-                                node);
+       if (iptable->interface_name_list) {
+               for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node,
+                                      nnode, name)) {
+                       XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
+                       list_delete_node(iptable->interface_name_list, node);
+               }
+               list_delete(&iptable->interface_name_list);
        }
        XFREE(MTYPE_TMP, iptable);
 }
@@ -689,6 +691,7 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
                        list_delete_node(iptable->interface_name_list,
                                         node);
                }
+               list_delete(&iptable->interface_name_list);
                XFREE(MTYPE_TMP, lookup);
        } else
                zlog_debug("%s: IPTable being deleted we know nothing about",