From: Roy Marples Date: Thu, 20 Feb 2025 13:41:34 +0000 (+0000) Subject: BSD: Loop when pulling routes into our buffer if no memory X-Git-Tag: v10.2.1~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f7a6397be0051dce246f1caee908e873e0853633;p=thirdparty%2Fdhcpcd.git BSD: Loop when pulling routes into our buffer if no memory We need to make two sysctls to pull the route table from the kernel. The first one works out the size of the buffer required and the second one populates it. It's possible for more routes to be added between these two calls causing the second call to fail with ENOMEM. If this happens, just re-query the size needed and try again. Fixes #466. --- diff --git a/src/if-bsd.c b/src/if-bsd.c index 32b51ba7..9871d78b 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -965,19 +965,24 @@ if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af) struct rt_msghdr *rtm; int mib[6] = { CTL_NET, PF_ROUTE, 0, af, NET_RT_DUMP, 0 }; size_t bufl; - char *buf, *p, *end; + char *buf = NULL, *p, *end; struct rt rt, *rtn; +again: if (if_sysctl(ctx, mib, __arraycount(mib), NULL, &bufl, NULL, 0) == -1) - return -1; - if (bufl == 0) + goto err; + if (bufl == 0) { + free(buf); return 0; - if ((buf = malloc(bufl)) == NULL) - return -1; + } + if ((p = realloc(buf, bufl)) == NULL) + goto err; + buf = p; if (if_sysctl(ctx, mib, __arraycount(mib), buf, &bufl, NULL, 0) == -1) { - free(buf); - return -1; + if (errno == ENOMEM) + goto again; + goto err; } end = buf + bufl; @@ -1001,6 +1006,10 @@ if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af) } free(buf); return p == end ? 0 : -1; + +err: + free(buf); + return -1; } #ifdef INET