summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2013-03-21 04:43:18 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2013-03-21 04:43:18 +0000
commit754cb70adb1ca0ca659a5ce03277ef4d80963a6c (patch)
treec99c4d3ade0562fb129f705dbc06ba1ad3e5ac59
parent58df33a7a6c5d7ffd49bd390800651664a203c43 (diff)
create realloc() loops around sysctl for array-based mibs, in programs
which want a "full" dump ok dlg
-rw-r--r--sbin/dhclient/kroute.c35
-rw-r--r--sbin/route/route.c20
-rw-r--r--sbin/route/show.c20
-rw-r--r--usr.sbin/arp/arp.c28
-rw-r--r--usr.sbin/ndp/ndp.c25
-rw-r--r--usr.sbin/route6d/route6d.c30
-rw-r--r--usr.sbin/rtadvd/if.c24
-rw-r--r--usr.sbin/rwhod/rwhod.c24
8 files changed, 124 insertions, 82 deletions
diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c
index bcb8292f855..17e8a9f85b2 100644
--- a/sbin/dhclient/kroute.c
+++ b/sbin/dhclient/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.44 2013/03/13 16:28:05 weerd Exp $ */
+/* $OpenBSD: kroute.c,v 1.45 2013/03/21 04:43:17 deraadt Exp $ */
/*
* Copyright 2012 Kenneth R Westerback <krw@openbsd.org>
@@ -79,13 +79,13 @@ priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg)
struct sockaddr *rti_info[RTAX_MAX];
int mib[7];
size_t needed;
- char *lim, *buf, *next, *errmsg;
+ char *lim, *buf = NULL, *bufp, *next, *errmsg = NULL;
struct rt_msghdr *rtm;
struct sockaddr *sa;
struct sockaddr_dl *sdl;
struct sockaddr_in *sa_in;
struct sockaddr_rtlabel *sa_rl;
- int s, seqno = 0, rlen, retry;
+ int s, seqno = 0, rlen;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@@ -95,31 +95,34 @@ priv_flush_routes_and_arp_cache(struct imsg_flush_routes *imsg)
mib[5] = 0;
mib[6] = imsg->rdomain;
- buf = NULL;
- retry = 0;
- do {
- retry++;
- errmsg = NULL;
- if (buf)
- free(buf);
+ while (1) {
if (sysctl(mib, 7, NULL, &needed, NULL, 0) == -1) {
errmsg = "sysctl size of routes:";
- continue;
+ break;
}
- if (needed == 0)
+ if (needed == 0) {
+ free(buf);
return;
- if ((buf = malloc(needed)) == NULL) {
+ }
+ if ((bufp = realloc(buf, needed)) == NULL) {
+ free(buf);
errmsg = "routes buf malloc:";
continue;
}
+ buf = bufp;
if (sysctl(mib, 7, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
+ free(buf);
errmsg = "sysctl retrieval of routes:";
+ break;
}
- } while (retry < 10 && errmsg != NULL);
+ break;
+ }
if (errmsg) {
- warning("route cleanup failed - %s %s (%d retries, msize=%zu)",
- errmsg, strerror(errno), retry, needed);
+ warning("route cleanup failed - %s %s (msize=%zu)",
+ errmsg, strerror(errno), needed);
return;
}
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 45460e1321c..c623d4ff7a8 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.160 2012/12/04 02:30:33 deraadt Exp $ */
+/* $OpenBSD: route.c,v 1.161 2013/03/21 04:43:17 deraadt Exp $ */
/* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */
/*
@@ -286,14 +286,20 @@ flushroutes(int argc, char **argv)
mib[4] = NET_RT_DUMP;
mib[5] = 0; /* no flags */
mib[6] = tableid;
- if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0)
- err(1, "route-sysctl-estimate");
- if (needed) {
- if ((buf = malloc(needed)) == NULL)
- err(1, "malloc");
- if (sysctl(mib, 7, buf, &needed, NULL, 0) < 0)
+ while (1) {
+ if (sysctl(mib, 7, NULL, &needed, NULL, 0) == -1)
+ err(1, "route-sysctl-estimate");
+ if (needed == 0)
+ break;
+ if ((buf = realloc(buf, needed)) == NULL)
+ err(1, "realloc");
+ if (sysctl(mib, 7, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
err(1, "actual retrieval of routing table");
+ }
lim = buf + needed;
+ break;
}
if (verbose) {
printf("Examining routing table from sysctl\n");
diff --git a/sbin/route/show.c b/sbin/route/show.c
index 961e9ababe9..8a485d1d9f8 100644
--- a/sbin/route/show.c
+++ b/sbin/route/show.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: show.c,v 1.92 2012/12/04 02:30:33 deraadt Exp $ */
+/* $OpenBSD: show.c,v 1.93 2013/03/21 04:43:17 deraadt Exp $ */
/* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */
/*
@@ -142,14 +142,20 @@ p_rttables(int af, u_int tableid, int hastable)
} else
mcnt = 6;
- if (sysctl(mib, mcnt, NULL, &needed, NULL, 0) < 0)
- err(1, "route-sysctl-estimate");
- if (needed > 0) {
- if ((buf = malloc(needed)) == 0)
- err(1, NULL);
- if (sysctl(mib, mcnt, buf, &needed, NULL, 0) < 0)
+ while (1) {
+ if (sysctl(mib, mcnt, NULL, &needed, NULL, 0) == -1)
+ err(1, "route-sysctl-estimate");
+ if (needed == 0)
+ break;
+ if ((buf = realloc(buf, needed)) == NULL)
+ err(1, "realloc");
+ if (sysctl(mib, mcnt, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
err(1, "sysctl of routing table");
+ }
lim = buf + needed;
+ break;
}
printf("Routing tables\n");
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 95e079cf7ff..56b8390f954 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arp.c,v 1.51 2012/11/08 11:05:41 phessler Exp $ */
+/* $OpenBSD: arp.c,v 1.52 2013/03/21 04:43:17 deraadt Exp $ */
/* $NetBSD: arp.c,v 1.12 1995/04/24 13:25:18 cgd Exp $ */
/*
@@ -442,7 +442,7 @@ search(in_addr_t addr, void (*action)(struct sockaddr_dl *sdl,
{
int mib[7];
size_t needed;
- char *lim, *buf, *next;
+ char *lim, *buf = NULL, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
@@ -454,15 +454,21 @@ search(in_addr_t addr, void (*action)(struct sockaddr_dl *sdl,
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
mib[6] = rdomain;
- if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0)
- err(1, "route-sysctl-estimate");
- if (needed == 0)
- return;
- if ((buf = malloc(needed)) == NULL)
- err(1, "malloc");
- if (sysctl(mib, 7, buf, &needed, NULL, 0) < 0)
- err(1, "actual retrieval of routing table");
- lim = buf + needed;
+ while (1) {
+ if (sysctl(mib, 7, NULL, &needed, NULL, 0) == -1)
+ err(1, "route-sysctl-estimate");
+ if (needed == 0)
+ return;
+ if ((buf = realloc(buf, needed)) == NULL)
+ err(1, "malloc");
+ if (sysctl(mib, 7, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
+ err(1, "actual retrieval of routing table");
+ }
+ lim = buf + needed;
+ break;
+ }
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
if (rtm->rtm_version != RTM_VERSION)
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index 5fb2db7cd29..28aed85098b 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ndp.c,v 1.46 2013/03/11 14:02:37 mpi Exp $ */
+/* $OpenBSD: ndp.c,v 1.47 2013/03/21 04:43:17 deraadt Exp $ */
/* $KAME: ndp.c,v 1.101 2002/07/17 08:46:33 itojun Exp $ */
/*
@@ -544,7 +544,7 @@ dump(struct in6_addr *addr, int cflag)
{
int mib[6];
size_t needed;
- char *lim, *buf, *next;
+ char *lim, *buf = NULL, *next;
struct rt_msghdr *rtm;
struct sockaddr_in6 *sin;
struct sockaddr_dl *sdl;
@@ -569,16 +569,21 @@ again:;
mib[3] = AF_INET6;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
- err(1, "sysctl(PF_ROUTE estimate)");
- if (needed > 0) {
- if ((buf = malloc(needed)) == NULL)
- err(1, "malloc");
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+ while (1) {
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ err(1, "sysctl(PF_ROUTE estimate)");
+ if (needed == 0)
+ break;
+ if ((buf = realloc(buf, needed)) == NULL)
+ err(1, "realloc");
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
err(1, "sysctl(PF_ROUTE, NET_RT_FLAGS)");
+ }
lim = buf + needed;
- } else
- buf = lim = NULL;
+ break;
+ }
for (next = buf; next && next < lim; next += rtm->rtm_msglen) {
int isrouter = 0, prbs = 0;
diff --git a/usr.sbin/route6d/route6d.c b/usr.sbin/route6d/route6d.c
index 00ba8e12a0f..450e7140db4 100644
--- a/usr.sbin/route6d/route6d.c
+++ b/usr.sbin/route6d/route6d.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route6d.c,v 1.55 2009/10/27 23:59:54 deraadt Exp $ */
+/* $OpenBSD: route6d.c,v 1.56 2013/03/21 04:43:17 deraadt Exp $ */
/* $KAME: route6d.c,v 1.111 2006/10/25 06:38:13 jinmei Exp $ */
/*
@@ -2257,8 +2257,8 @@ int
getifmtu(int ifindex)
{
int mib[6];
- char *buf;
- size_t msize;
+ char *buf = NULL;
+ size_t needed;
struct if_msghdr *ifm;
int mtu;
@@ -2268,17 +2268,19 @@ getifmtu(int ifindex)
mib[3] = AF_INET6;
mib[4] = NET_RT_IFLIST;
mib[5] = ifindex;
- if (sysctl(mib, 6, NULL, &msize, NULL, 0) < 0) {
- fatal("sysctl estimate NET_RT_IFLIST");
- /*NOTREACHED*/
- }
- if ((buf = malloc(msize)) == NULL) {
- fatal("malloc");
- /*NOTREACHED*/
- }
- if (sysctl(mib, 6, buf, &msize, NULL, 0) < 0) {
- fatal("sysctl NET_RT_IFLIST");
- /*NOTREACHED*/
+ while (1) {
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ fatal("sysctl estimate NET_RT_IFLIST");
+ if (needed == 0)
+ break;
+ if ((buf = realloc(buf, needed)) == NULL)
+ fatal("malloc");
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
+ fatal("sysctl NET_RT_IFLIST");
+ }
+ break;
}
ifm = (struct if_msghdr *)buf;
mtu = ifm->ifm_data.ifi_mtu;
diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c
index 0917ff2851c..eb3f464adbc 100644
--- a/usr.sbin/rtadvd/if.c
+++ b/usr.sbin/rtadvd/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.24 2011/07/05 05:13:04 claudio Exp $ */
+/* $OpenBSD: if.c,v 1.25 2013/03/21 04:43:15 deraadt Exp $ */
/* $KAME: if.c,v 1.17 2001/01/21 15:27:30 itojun Exp $ */
/*
@@ -437,14 +437,20 @@ get_iflist(char **buf, size_t *size)
mib[3] = AF_INET6;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
-
- if (sysctl(mib, 6, NULL, size, NULL, 0) < 0)
- fatal("sysctl: iflist size get failed");
- if ((*buf = malloc(*size)) == NULL)
- fatal("malloc");
- if (sysctl(mib, 6, *buf, size, NULL, 0) < 0)
- fatal("sysctl: iflist get failed");
- return;
+ while (1) {
+ if (sysctl(mib, 6, NULL, size, NULL, 0) == -1)
+ fatal("sysctl: iflist size get failed");
+ if (*size == 0)
+ break;
+ if ((*buf = realloc(*buf, *size)) == NULL)
+ fatal("malloc");
+ if (sysctl(mib, 6, *buf, size, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
+ fatal("sysctl: iflist get failed");
+ }
+ break;
+ }
}
/*
diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c
index 5a77492d007..61b6c8288a5 100644
--- a/usr.sbin/rwhod/rwhod.c
+++ b/usr.sbin/rwhod/rwhod.c
@@ -469,7 +469,7 @@ configure(void)
struct sockaddr_dl *sdl;
size_t needed;
int mib[6], flags = 0, len;
- char *buf, *lim, *next;
+ char *buf = NULL, *lim, *next;
struct rt_addrinfo info;
mib[0] = CTL_NET;
@@ -478,13 +478,21 @@ configure(void)
mib[3] = AF_INET;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
- if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
- quit("route-sysctl-estimate");
- if ((buf = malloc(needed)) == NULL)
- quit("malloc");
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
- quit("actual retrieval of interface table");
- lim = buf + needed;
+ while (1) {
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
+ quit("route-sysctl-estimate");
+ if (needed == 0)
+ break;
+ if ((buf = realloc(buf, needed)) == NULL)
+ quit("realloc");
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
+ if (errno == ENOMEM)
+ continue;
+ quit("actual retrieval of interface table");
+ }
+ lim = buf + needed;
+ break;
+ }
sdl = NULL; /* XXX just to keep gcc -Wall happy */
for (next = buf; next < lim; next += ifm->ifm_msglen) {