]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Add calls to nvlist_destroy to avoid leaks
authorRémi Farault <remi.farault@stormshield.eu>
Tue, 29 Oct 2024 11:06:35 +0000 (12:06 +0100)
committerGert Doering <gert@greenie.muc.de>
Tue, 5 Nov 2024 15:29:56 +0000 (16:29 +0100)
Some memory leaks were detected by valgrind on the openvpn daemon, using
DCO mode on a FreeBSD platform.  The leaks are caused by missing
nvlist_destroy calls in the file dco_freebsd.c.

Calls to nvlist_destroy were added, sometimes using local variables to
store nvlist pointers temporarly.  A valgrind run on the updated daemon
confirmed that  the leaks were gone.

Github: OpenVPN/openvpn#636
Signed-off-by: Rémi Farault <remi.farault@stormshield.eu>
Acked-by: Kristof Provost <kp@freebsd.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <f8845c0c5aa74e5bab537463249a251d@stormshield.eu>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg29701.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/dco_freebsd.c

index c92e42a1a84c173ce4bf07f1a2197dce21271e0d..f4c3b021a97836ab0fe0bf6ecb1920e7fdc12fba 100644 (file)
@@ -78,7 +78,7 @@ dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
              struct in_addr *vpn_ipv4, struct in6_addr *vpn_ipv6)
 {
     struct ifdrv drv;
-    nvlist_t *nvl;
+    nvlist_t *nvl, *local_nvl, *remote_nvl;
     int ret;
 
     nvl = nvlist_create(0);
@@ -87,12 +87,14 @@ dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
 
     if (localaddr)
     {
-        nvlist_add_nvlist(nvl, "local", sockaddr_to_nvlist(localaddr));
+        local_nvl = sockaddr_to_nvlist(localaddr);
+        nvlist_add_nvlist(nvl, "local", local_nvl);
     }
 
     if (remoteaddr)
     {
-        nvlist_add_nvlist(nvl, "remote", sockaddr_to_nvlist(remoteaddr));
+        remote_nvl = sockaddr_to_nvlist(remoteaddr);
+        nvlist_add_nvlist(nvl, "remote", remote_nvl);
     }
 
     if (vpn_ipv4)
@@ -121,6 +123,14 @@ dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
     }
 
     free(drv.ifd_data);
+    if (localaddr)
+    {
+        nvlist_destroy(local_nvl);
+    }
+    if (remoteaddr)
+    {
+        nvlist_destroy(remote_nvl);
+    }
     nvlist_destroy(nvl);
 
     return ret;
@@ -418,7 +428,7 @@ dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
             const char *ciphername)
 {
     struct ifdrv drv;
-    nvlist_t *nvl;
+    nvlist_t *nvl, *encrypt_nvl, *decrypt_nvl;
     int ret;
 
     msg(D_DCO_DEBUG, "%s: slot %d, key-id %d, peer-id %d, cipher %s",
@@ -430,10 +440,11 @@ dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
     nvlist_add_number(nvl, "keyid", keyid);
     nvlist_add_number(nvl, "peerid", peerid);
 
-    nvlist_add_nvlist(nvl, "encrypt",
-                      key_to_nvlist(encrypt_key, encrypt_iv, ciphername));
-    nvlist_add_nvlist(nvl, "decrypt",
-                      key_to_nvlist(decrypt_key, decrypt_iv, ciphername));
+    encrypt_nvl = key_to_nvlist(encrypt_key, encrypt_iv, ciphername);
+    decrypt_nvl = key_to_nvlist(decrypt_key, decrypt_iv, ciphername);
+
+    nvlist_add_nvlist(nvl, "encrypt", encrypt_nvl);
+    nvlist_add_nvlist(nvl, "decrypt", decrypt_nvl);
 
     CLEAR(drv);
     snprintf(drv.ifd_name, IFNAMSIZ, "%s", dco->ifname);
@@ -451,6 +462,8 @@ dco_new_key(dco_context_t *dco, unsigned int peerid, int keyid,
     }
 
     free(drv.ifd_data);
+    nvlist_destroy(encrypt_nvl);
+    nvlist_destroy(decrypt_nvl);
     nvlist_destroy(nvl);
 
     return ret;
@@ -750,6 +763,7 @@ retry:
     if (!nvlist_exists_nvlist_array(nvl, "peers"))
     {
         /* no peers */
+        nvlist_destroy(nvl);
         return 0;
     }
 
@@ -762,6 +776,7 @@ retry:
         dco_update_peer_stat(m, peerid, nvlist_get_nvlist(peer, "bytes"));
     }
 
+    nvlist_destroy(nvl);
     return 0;
 }