Re: Memory leak in snmpd(8)

2012-05-25 Thread Joel Knight
On Thu, May 24, 2012 at 8:16 AM, Kenneth R Westerback
kwesterb...@rogers.com wrote:

 Calling mib_carpget() seems a tad over complex. Wouldn't the diff
 below make it cleaner? Untested except by gcc.

 And doesn't the socket 's' leak too, or does SIOCGVH returning -1
 mean 's' was closed?

Ken,

Your diff looks good to me. I also found a few spots that leak in
pf.c. All combined I've come up with this diff. Ok?


Index: src/usr.sbin/snmpd/mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.52
diff -p -u -r1.52 mib.c
--- src/usr.sbin/snmpd/mib.c20 Mar 2012 03:01:26 -  1.52
+++ src/usr.sbin/snmpd/mib.c26 May 2012 05:14:36 -
@@ -1360,7 +1360,7 @@ intmib_carpstats(struct oid *, struct
 int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element **);
 int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element **);
 struct carpif
-   *mib_carpifget(struct carpif *, u_int);
+   *mib_carpifget(u_int);
 int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element **);

 static struct oid openbsd_mib[] = {
@@ -2647,9 +2647,10 @@ mib_carpifnum(struct oid *oid, struct be
 }

 struct carpif *
-mib_carpifget(struct carpif *cif, u_int idx)
+mib_carpifget(u_int idx)
 {
struct kif  *kif;
+   struct carpif   *cif;
int  s;
struct ifreq ifr;
struct carpreq   carpr;
@@ -2689,12 +2690,17 @@ mib_carpifget(struct carpif *cif, u_int
memset((char *)carpr, 0, sizeof(carpr));
ifr.ifr_data = (caddr_t)carpr;

-   if (ioctl(s, SIOCGVH, (caddr_t)ifr) == -1)
+   if (ioctl(s, SIOCGVH, (caddr_t)ifr) == -1) {
+   close(s);
return (NULL);
+   }

-   memset(cif, 0, sizeof(struct carpif));
-   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
-   memcpy(cif-kif, kif, sizeof(struct kif));
+   cif = malloc(sizeof(struct carpif));
+   if (cif != NULL) {
+   memset(cif, 0, sizeof(struct carpif));
+   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
+   memcpy(cif-kif, kif, sizeof(struct kif));
+   }

close(s);

@@ -2707,16 +2713,11 @@ mib_carpiftable(struct oid *oid, struct
u_int32_tidx;
struct carpif   *cif;

-   if ((cif = malloc(sizeof(struct carpif))) == NULL)
-   return (1);
-
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];

-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
-   free(cif);
+   if ((cif = mib_carpifget(idx)) == NULL)
return (1);
-   }

/* Tables need to prepend the OID on their own */
o-bo_id[OIDIDX_carpIfEntry] = cif-kif.if_index;
Index: src/usr.sbin/snmpd/pf.c
===
RCS file: /cvs/src/usr.sbin/snmpd/pf.c,v
retrieving revision 1.2
diff -p -u -r1.2 pf.c
--- src/usr.sbin/snmpd/pf.c 14 May 2012 00:02:33 -  1.2
+++ src/usr.sbin/snmpd/pf.c 26 May 2012 05:22:04 -
@@ -228,8 +228,10 @@ pfi_count(void)
struct pfi_kif  *p;
int  c = 0;

-   if (pfi_get(b, NULL))
+   if (pfi_get(b, NULL)) {
+   free(b.pfrb_caddr);
return (-1);
+   }

PFRB_FOREACH(p, b)
c++;
@@ -245,8 +247,10 @@ pfi_get_if(struct pfi_kif *rp, int idx)
struct pfi_kif  *p;
int  i = 1;

-   if (pfi_get(b, NULL))
+   if (pfi_get(b, NULL)) {
+   free(b.pfrb_caddr);
return (-1);
+   }

PFRB_FOREACH(p, b) {
if (i == idx)
@@ -290,9 +294,11 @@ pft_get_table(struct pfr_tstats *rts, in
struct pfr_tstats   *ts;
int  i = 1;

-   if (pft_get(b, NULL))
+   if (pft_get(b, NULL)) {
+   free(b.pfrb_caddr);
return (-1);
-
+   }
+
PFRB_FOREACH(ts, b) {
if (!(ts-pfrts_flags  PFR_TFLAG_ACTIVE))
continue;
@@ -319,8 +325,10 @@ pft_count(void)
struct pfr_tstats   *ts;
int  c = 0;

-   if (pft_get(b, NULL))
+   if (pft_get(b, NULL)) {
+   free(b.pfrb_caddr);
return (-1);
+   }

PFRB_FOREACH(ts, b) {
if (!(ts-pfrts_flags  PFR_TFLAG_ACTIVE))



Memory leak in snmpd(8)

2012-05-24 Thread Gerhard Roth

Hi,

with the OPENBSD-CARP-MIB a memory leak was introduced to snmpd(8):

RCS file: mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   2012/03/20 03:01:26 1.52
+++ mib.c   2012/05/24 12:53:35
@@ -2713,7 +2713,7 @@ mib_carpiftable(struct oid *oid, struct ber_oid *o,
st
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];

-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
+   if (mib_carpifget(cif, idx) == NULL) {
free(cif);
return (1);
}


Gerhard

--
GeNUA, Gesellschaft fCr Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238



Re: Memory leak in snmpd(8)

2012-05-24 Thread Kenneth R Westerback
On Thu, May 24, 2012 at 01:54:36PM +0200, Gerhard Roth wrote:
 Hi,
 
 with the OPENBSD-CARP-MIB a memory leak was introduced to snmpd(8):
 
 RCS file: mib.c,v
 retrieving revision 1.52
 diff -u -p -r1.52 mib.c
 --- mib.c   2012/03/20 03:01:26 1.52
 +++ mib.c   2012/05/24 12:53:35
 @@ -2713,7 +2713,7 @@ mib_carpiftable(struct oid *oid, struct ber_oid *o,
 st
 /* Get and verify the current row index */
 idx = o-bo_id[OIDIDX_carpIfEntry];
 
 -   if ((cif = mib_carpifget(cif, idx)) == NULL) {
 +   if (mib_carpifget(cif, idx) == NULL) {
 free(cif);
 return (1);
 }
 
 
 Gerhard
 
 --
 GeNUA, Gesellschaft fCr Netzwerk- und Unix-Administration mbH
 Domagkstrasse 7, 85551 Kirchheim bei Muenchen
 tel +49 89 991950-0, fax -999, www.genua.de
 Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
 Bernhard Schneck. Amtsgericht Muenchen HRB 98238
 

Calling mib_carpget() seems a tad over complex. Wouldn't the diff
below make it cleaner? Untested except by gcc.

And doesn't the socket 's' leak too, or does SIOCGVH returning -1
mean 's' was closed?

 Ken

Index: mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   20 Mar 2012 03:01:26 -  1.52
+++ mib.c   24 May 2012 14:11:22 -
@@ -1360,7 +1360,7 @@ intmib_carpstats(struct oid *, struct 
 int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element **);
 int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element **);
 struct carpif
-   *mib_carpifget(struct carpif *, u_int);
+   *mib_carpifget(u_int);
 int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element **);
 
 static struct oid openbsd_mib[] = {
@@ -2647,9 +2647,10 @@ mib_carpifnum(struct oid *oid, struct be
 }
 
 struct carpif *
-mib_carpifget(struct carpif *cif, u_int idx)
+mib_carpifget(u_int idx)
 {
struct kif  *kif;
+   struct carpif   *cif;
int  s;
struct ifreq ifr;
struct carpreq   carpr;
@@ -2692,9 +2693,12 @@ mib_carpifget(struct carpif *cif, u_int 
if (ioctl(s, SIOCGVH, (caddr_t)ifr) == -1)
return (NULL);
 
-   memset(cif, 0, sizeof(struct carpif));
-   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
-   memcpy(cif-kif, kif, sizeof(struct kif));
+   cif = malloc(sizeof(struct carpif));
+   if (cif != NULL) {
+   memset(cif, 0, sizeof(struct carpif));
+   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
+   memcpy(cif-kif, kif, sizeof(struct kif));
+   }
 
close(s);
 
@@ -2707,16 +2711,11 @@ mib_carpiftable(struct oid *oid, struct 
u_int32_tidx;
struct carpif   *cif;
 
-   if ((cif = malloc(sizeof(struct carpif))) == NULL)
-   return (1);
-
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];
 
-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
-   free(cif);
+   if ((cif = mib_carpifget(idx)) == NULL)
return (1);
-   }
 
/* Tables need to prepend the OID on their own */
o-bo_id[OIDIDX_carpIfEntry] = cif-kif.if_index;



Re: Memory leak in snmpd(8)

2012-05-24 Thread Gerhard Roth

On Thu, 24 May 2012 16:16:02 +0200, Kenneth R Westerback
kwesterb...@rogers.com wrote:

On Thu, May 24, 2012 at 01:54:36PM +0200, Gerhard Roth wrote:

Hi,

with the OPENBSD-CARP-MIB a memory leak was introduced to snmpd(8):

RCS file: mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   2012/03/20 03:01:26 1.52
+++ mib.c   2012/05/24 12:53:35
@@ -2713,7 +2713,7 @@ mib_carpiftable(struct oid *oid, struct ber_oid
*o,
st
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];

-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
+   if (mib_carpifget(cif, idx) == NULL) {
free(cif);
return (1);
}


Gerhard



Calling mib_carpget() seems a tad over complex. Wouldn't the diff
below make it cleaner? Untested except by gcc.

And doesn't the socket 's' leak too, or does SIOCGVH returning -1
mean 's' was closed?

 Ken

Index: mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.52
diff -u -p -r1.52 mib.c
--- mib.c   20 Mar 2012 03:01:26 -  1.52
+++ mib.c   24 May 2012 14:11:22 -
@@ -1360,7 +1360,7 @@ intmib_carpstats(struct oid *, struct
 int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element
**);
 int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element
**);
 struct carpif
-   *mib_carpifget(struct carpif *, u_int);
+   *mib_carpifget(u_int);
 int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element
**);
static struct oid openbsd_mib[] = {
@@ -2647,9 +2647,10 @@ mib_carpifnum(struct oid *oid, struct be
 }
struct carpif *
-mib_carpifget(struct carpif *cif, u_int idx)
+mib_carpifget(u_int idx)
 {
struct kif  *kif;
+   struct carpif   *cif;
int  s;
struct ifreq ifr;
struct carpreq   carpr;
@@ -2692,9 +2693,12 @@ mib_carpifget(struct carpif *cif, u_int
if (ioctl(s, SIOCGVH, (caddr_t)ifr) == -1)
return (NULL);
-   memset(cif, 0, sizeof(struct carpif));
-   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
-   memcpy(cif-kif, kif, sizeof(struct kif));
+   cif = malloc(sizeof(struct carpif));
+   if (cif != NULL) {
+   memset(cif, 0, sizeof(struct carpif));
+   memcpy(cif-carpr, carpr, sizeof(struct carpreq));
+   memcpy(cif-kif, kif, sizeof(struct kif));
+   }
close(s);
@@ -2707,16 +2711,11 @@ mib_carpiftable(struct oid *oid, struct
u_int32_tidx;
struct carpif   *cif;
-   if ((cif = malloc(sizeof(struct carpif))) == NULL)
-   return (1);
-
/* Get and verify the current row index */
idx = o-bo_id[OIDIDX_carpIfEntry];
-   if ((cif = mib_carpifget(cif, idx)) == NULL) {
-   free(cif);
+   if ((cif = mib_carpifget(idx)) == NULL)
return (1);
-   }
/* Tables need to prepend the OID on their own */
o-bo_id[OIDIDX_carpIfEntry] = cif-kif.if_index;



Hi Ken,

I like your patch; it's better than mine.

And you are right about the socket fd leak. If an ioctl()
would close the filedes passed in that would be a very
awkward API.

Gerhard

--
GeNUA, Gesellschaft fCr Netzwerk- und Unix-Administration mbH
Domagkstrasse 7, 85551 Kirchheim bei Muenchen
tel +49 89 991950-0, fax -999, www.genua.de
Geschaeftsfuehrer: Dr. Magnus Harlander, Dr. Michaela Harlander,
Bernhard Schneck. Amtsgericht Muenchen HRB 98238