On Wed, Dec 19 2018, Ed Hynan <eh_l...@optonline.net> wrote:
> net/wmnetload has a memory leak [patch]
>
> wmnetload (6.4 release) repeatedly calls getifaddrs(3)
> without freeifaddrs.

Indeed.

> The patch here fixes and would replace
> net/wmnetload/patches/patch-src_ifstat_openbsd_c
> not apply over it.

Thanks.  If you want to make it easier for people to pick up your
patches, please try to submit patches using make update-patches and cvs
diff.  For more information on how to use update-patches, see item 11:

  https://www.openbsd.org/faq/ports/guide.html

Since the fix changes what ends up in the package, it should include
a REVISION bump.

> Also fixes a compile warning from strcmp() w/o <string.h>

Yep.

Here's a reworked version, not directly based on your diff.  There's no
need to keep around what getifaddrs(3) returns, we can always free it.
This simplifies the memory management and appears to fix the memory leak
in the current package.  I have no idea if wmnetload actually works, it
seems to just draw an empty black window under my window manager.

Could you please test this and report back?


Index: Makefile
===================================================================
RCS file: /cvs/ports/net/wmnetload/Makefile,v
retrieving revision 1.13
diff -u -p -r1.13 Makefile
--- Makefile    7 Dec 2015 14:58:54 -0000       1.13
+++ Makefile    19 Dec 2018 18:29:20 -0000
@@ -3,7 +3,7 @@
 COMMENT=               wm-dockapp; simple network interface monitoring tool
 
 DISTNAME=              wmnetload-1.3
-REVISION=              3
+REVISION=              4
 CATEGORIES=            net x11 x11/windowmaker
 
 HOMEPAGE=              http://freshmeat.net/projects/wmnetload
Index: patches/patch-src_ifstat_openbsd_c
===================================================================
RCS file: /cvs/ports/net/wmnetload/patches/patch-src_ifstat_openbsd_c,v
retrieving revision 1.2
diff -u -p -r1.2 patch-src_ifstat_openbsd_c
--- patches/patch-src_ifstat_openbsd_c  7 Dec 2015 14:58:54 -0000       1.2
+++ patches/patch-src_ifstat_openbsd_c  19 Dec 2018 18:29:20 -0000
@@ -2,9 +2,10 @@ $OpenBSD: patch-src_ifstat_openbsd_c,v 1
 
 use getifaddrs(3) instead of libkvm.
 
---- src/ifstat_openbsd.c.orig  Tue Jan 29 09:09:18 2002
-+++ src/ifstat_openbsd.c       Mon Dec  7 14:31:38 2015
-@@ -27,19 +27,14 @@
+Index: src/ifstat_openbsd.c
+--- src/ifstat_openbsd.c.orig
++++ src/ifstat_openbsd.c
+@@ -27,10 +27,7 @@
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <net/if.h>
@@ -14,19 +15,24 @@ use getifaddrs(3) instead of libkvm.
 -#include <nlist.h>
 +#include <ifaddrs.h>
  #include <stdlib.h>
--#include <string.h>
+ #include <string.h>
  
- #include "ifstat.h"
+@@ -38,21 +35,16 @@
  #include "utils.h"
  
  struct ifstatstate {
 -      void    *ifnet_head;
 -      kvm_t   *kd;
-+      struct ifaddrs *ifap;
++      int unused;
  };
  
  /*
-@@ -51,8 +46,6 @@ ifstatstate_t *
+- * Do one-time setup stuff for accessing the interface statistics and store
+- * the gathered information in an interface statistics state structure.
+- * Return the state structure.
++ * Return a dummy state structure.
+  */
+ ifstatstate_t *
  if_statinit(void)
  {
        ifstatstate_t   *statep;
@@ -35,7 +41,7 @@ use getifaddrs(3) instead of libkvm.
  
        statep = malloc(sizeof (ifstatstate_t));
        if (statep == NULL) {
-@@ -60,35 +53,8 @@ if_statinit(void)
+@@ -60,63 +52,44 @@ if_statinit(void)
                return (NULL);
        }
  
@@ -66,60 +72,67 @@ use getifaddrs(3) instead of libkvm.
 -      }
 -
        return (statep);
- fail:
+-fail:
 -      (void) kvm_close(statep->kd);
-       free(statep);
-       return (NULL);
+-      free(statep);
+-      return (NULL);
  }
-@@ -100,22 +66,33 @@ fail:
+ 
+ /*
+- * Optionally using state stored in `statep', retrieve stats on interface
+- * `ifname', and store the statistics in `ifstatsp'.
++ * Retrieve stats on interface `ifname', and store the statistics in 
`ifstatsp'.
+  */
  int
  if_stats(const char *ifname, ifstatstate_t *statep, ifstats_t *ifstatsp)
  {
 -      void            *ifnet_addr = statep->ifnet_head;
 -      struct ifnet    ifnet;
-+      struct ifaddrs *ifa;
++      struct ifaddrs  *ifa0, *ifa;
++      int              ret = 0;
  
 -      for (; ifnet_addr != NULL; ifnet_addr = TAILQ_NEXT(&ifnet, if_list)) {
-+      if (getifaddrs(&statep->ifap) != 0) {
-+              warn("failed to get interface addresses");
-+              return (0);
-+      }
++      (void)statep;
  
 -              if (kvm_read(statep->kd, (unsigned long)ifnet_addr, &ifnet,
 -                  sizeof (struct ifnet)) != sizeof (struct ifnet))
 -                      return (0);
-+      for (ifa = statep->ifap; ifa != NULL; ifa = ifa->ifa_next) {
-+              if (strcmp(ifname, ifa->ifa_name)) {
-+                      continue;
-+              }
++      if (getifaddrs(&ifa0) != 0) {
++              warn("failed to get interface addresses");
++              return (0);
++      }
  
 -              if (strcmp(ifnet.if_xname, ifname) == 0) {
 -                      ifstatsp->rxbytes = ifnet.if_ibytes;
 -                      ifstatsp->txbytes = ifnet.if_obytes;
 -                      return (1);
-+              if (ifa->ifa_addr->sa_family == AF_LINK) {
-+                      struct sockaddr_dl *dl = (struct sockaddr_dl 
*)ifa->ifa_addr;
-+                      struct if_data *ifd = NULL;
++      for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
++              if (strcmp(ifname, ifa->ifa_name)) {
++                      continue;
+               }
 +
-+                      ifd = ifa->ifa_data;
++              if (ifa->ifa_addr->sa_family == AF_LINK) {
++                      struct if_data *ifd = ifa->ifa_data;
 +
 +                      if (ifd != NULL) {
 +                              ifstatsp->rxbytes = ifd->ifi_ibytes;
 +                              ifstatsp->txbytes = ifd->ifi_obytes;
-+                              return 1;
++                              ret = 1;
++                              break;
 +                      }
-               }
++              }
        }
  
-+      freeifaddrs(statep->ifap);
-       return (0);
+-      return (0);
++      freeifaddrs(ifa0);
++      return (ret);
  }
  
-@@ -125,6 +102,6 @@ if_stats(const char *ifname, ifstatstate_t *statep, if
+ /*
+@@ -125,6 +98,5 @@ if_stats(const char *ifname, ifstatstate_t *statep, if
  void
  if_statfini(ifstatstate_t *statep)
  {
 -      (void) kvm_close(statep->kd);
-+      freeifaddrs(statep->ifap);
        free(statep);
  }


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to