]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Don't leak memory in rtadv.c code on shutdown
authorDonald Sharp <sharpd@nvidia.com>
Tue, 12 Dec 2023 18:29:47 +0000 (13:29 -0500)
committerDonald Sharp <sharpd@nvidia.com>
Tue, 12 Dec 2023 18:29:47 +0000 (13:29 -0500)
The adata variable was being leaked on shutdown since
it was calloc'ed.  There is no need to make this dynamic
memory.  Just choose a size and use that.  Add a bit
of code to ensure that if it's not large enough,
it will just stop and the developer will fix it.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/main.c
zebra/rtadv.c
zebra/rtadv.h

index 5dd830b54241487b94b1d12ea5ff77e85edee430..604d8974b3051cd93f9de05419df7caa7b3590b3 100644 (file)
@@ -432,6 +432,8 @@ int main(int argc, char **argv)
        zebra_vty_init();
        access_list_init();
        prefix_list_init();
+
+       rtadv_init();
        rtadv_cmd_init();
 /* PTM socket */
 #ifdef ZEBRA_PTM_SUPPORT
index 35df4eb97626a618392ef8e928b59ca22d6a7532..df444ee523254c9ffcffc7da315a893a47ad3d2b 100644 (file)
@@ -33,6 +33,7 @@
 extern struct zebra_privs_t zserv_privs;
 
 static uint32_t interfaces_configured_for_ra_from_bgp;
+#define RTADV_ADATA_SIZE 1024
 
 #if defined(HAVE_RTADV)
 
@@ -187,8 +188,9 @@ static void rtadv_send_packet(int sock, struct interface *ifp,
        struct cmsghdr *cmsgptr;
        struct in6_pktinfo *pkt;
        struct sockaddr_in6 addr;
-       static void *adata = NULL;
        unsigned char buf[RTADV_MSG_SIZE];
+       char adata[RTADV_ADATA_SIZE];
+
        struct nd_router_advert *rtadv;
        int ret;
        int len = 0;
@@ -199,22 +201,6 @@ static void rtadv_send_packet(int sock, struct interface *ifp,
        struct listnode *node;
        uint16_t pkt_RouterLifetime;
 
-       /*
-        * Allocate control message bufffer.  This is dynamic because
-        * CMSG_SPACE is not guaranteed not to call a function.  Note that
-        * the size will be different on different architectures due to
-        * differing alignment rules.
-        */
-       if (adata == NULL) {
-               /* XXX Free on shutdown. */
-               adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo)));
-
-               if (adata == NULL) {
-                       zlog_debug("%s: can't malloc control data", __func__);
-                       exit(-1);
-               }
-       }
-
        /* Logging of packet. */
        if (IS_ZEBRA_DEBUG_PACKET)
                zlog_debug("%s(%s:%u): Tx RA, socket %u", ifp->name,
@@ -3069,3 +3055,13 @@ uint32_t rtadv_get_interfaces_configured_from_bgp(void)
 {
        return interfaces_configured_for_ra_from_bgp;
 }
+
+void rtadv_init(void)
+{
+       if (CMSG_SPACE(sizeof(struct in6_pktinfo)) > RTADV_ADATA_SIZE) {
+               zlog_debug("%s: RTADV_ADATA_SIZE choosen will not work on this platform, please use a larger size",
+                          __func__);
+
+               exit(-1);
+       }
+}
index 1ec376a10626ffa28b7c064a9519b0a0d08c2c59..9d358d4b0d84934cac184a128a2c8b812455cf3d 100644 (file)
@@ -435,6 +435,7 @@ extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
 
 extern uint32_t rtadv_get_interfaces_configured_from_bgp(void);
 extern bool rtadv_compiled_in(void);
+extern void rtadv_init(void);
 
 #ifdef __cplusplus
 }