From 003e7e4928246e2b16e1f49b39d56f0258f7102c Mon Sep 17 00:00:00 2001 From: Mikolaj Golub Date: Wed, 1 Feb 2012 18:03:21 +0000 Subject: [PATCH] Try to avoid ambiguity when sysctl returns ENOMEM additionally checking the returned oldlen: when ENOMEM is due to the supplied buffer being too short the return oldlen is equal to buffer size. Without this additional check sockstat gets stuck in loop leaking the memory if the returned ENOMEM was due the exceeded memorylocked limit. This is easily can be observed running `limits -l 1k sockstat'. Submitted by: Andrey Zonov MFC after: 1 week --- usr.bin/sockstat/sockstat.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index dff776108ed..0114cc47822 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -296,7 +296,7 @@ gather_inet(int proto) break; if (errno == ENOENT) goto out; - if (errno != ENOMEM) + if (errno != ENOMEM || len != bufsize) err(1, "sysctlbyname()"); bufsize *= 2; } @@ -424,7 +424,7 @@ gather_unix(int proto) len = bufsize; if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) break; - if (errno != ENOMEM) + if (errno != ENOMEM || len != bufsize) err(1, "sysctlbyname()"); bufsize *= 2; } @@ -476,14 +476,15 @@ gather_unix(int proto) static void getfiles(void) { - size_t len; + size_t len, olen; - if ((xfiles = malloc(len = sizeof *xfiles)) == NULL) + olen = len = sizeof *xfiles; + if ((xfiles = malloc(len)) == NULL) err(1, "malloc()"); while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { - if (errno != ENOMEM) + if (errno != ENOMEM || len != olen) err(1, "sysctlbyname()"); - len *= 2; + olen = len *= 2; if ((xfiles = realloc(xfiles, len)) == NULL) err(1, "realloc()"); }