惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
WordPress大学
WordPress大学
U
Unit 42
I
InfoQ
A
About on SuperTechFans
宝玉的分享
宝玉的分享
J
Java Code Geeks
博客园 - 司徒正美
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
腾讯CDC
Recent Announcements
Recent Announcements

dnsmasq-discuss

[Dnsmasq-discuss] Announce: dnsmasq-2.92rc2 Re: [Dnsmasq-discuss] [PATCH] Fix arguments order for chaos subdomain check Re: [Dnsmasq-discuss] patch: block-file/allow-file - for review/feedback Re: [Dnsmasq-discuss] patch: block-file/allow-file - for review/feedback Re: [Dnsmasq-discuss] patch: block-file/allow-file - for review/feedback Re: [Dnsmasq-discuss] patch: block-file/allow-file - for review/feedback [Dnsmasq-discuss] patch: block-file/allow-file - for review/feedback Re: [Dnsmasq-discuss] server= with interface parameter changes behavior over time [Dnsmasq-discuss] NFTsets and hosts-files [Dnsmasq-discuss] [PATCH] Allow expired RRSIGs when stale caching is enabled [Dnsmasq-discuss] [PATCH] Fix local host records being overridden by upstream NXDOMAIN [Dnsmasq-discuss] [PATCH] Fix arguments order for chaos subdomain check Re: [Dnsmasq-discuss] Malformed RRSIG Can Crash dnsmasq [Dnsmasq-discuss] Malformed NSEC/NSEC3 Can Hang dnsmasq [Dnsmasq-discuss] Malformed RRSIG Can Crash dnsmasq [Dnsmasq-discuss] Security - IMPORTANT Re: [Dnsmasq-discuss] Issue with circuit-id matching on dhcp requests Re: [Dnsmasq-discuss] Issue with circuit-id matching on dhcp requests Re: [Dnsmasq-discuss] Issue with circuit-id matching on dhcp requests [Dnsmasq-discuss] Issue with circuit-id matching on dhcp requests Re: [Dnsmasq-discuss] [PATCH] bpf.c: fix memory leak in arp_enumerate() on BSD Re: [Dnsmasq-discuss] [PATCH] bpf.c: fix memory leak in arp_enumerate() on BSD Re: [Dnsmasq-discuss] dnssec problem here and now Re: [Dnsmasq-discuss] dnssec problem here and now [Dnsmasq-discuss] dnssec problem here and now Re: [Dnsmasq-discuss] server= with interface parameter changes behavior over time Re: [Dnsmasq-discuss] [PATCH] bpf.c: fix memory leak in arp_enumerate() on BSD Re: [Dnsmasq-discuss] [PATCH] Preserve existing log file permissions when adding group-write bit. [Dnsmasq-discuss] server= with interface parameter changes behavior over time [Dnsmasq-discuss] [PATCH] bpf.c: fix memory leak in arp_enumerate() on BSD
Re: [Dnsmasq-discuss] [PATCH] bpf.c: fix memory leak in a...
Sagie D. · 2026-04-29 · via dnsmasq-discuss
I tried reapplying the previous patch on another folder and realized
the diff was malformed, so I'm attaching a fixed patch diff -- sorry
about that.
This fixed patch also adds NULL checks to avoid attempting to free an
unallocated buffer in edge cases.

Signed-off-by: Sagie D.
---
diff --git a/src/bpf.c b/src/bpf.c
index dd67735..e5bf6d9 100644
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -77,14 +77,20 @@ int arp_enumerate(void *parm, callback_t callback)
   while (1)
     {
       if (!expand_buf(&buff, needed))
-       return 0;
+        {
+          if (buff.iov_base) free(buff.iov_base);
+          return 0;
+        }
       if ((rc = sysctl(mib, 6, buff.iov_base, &needed, NULL, 0)) == 0 ||
-         errno != ENOMEM)
-       break;
+          errno != ENOMEM)
+        break;
       needed += needed / 8;
     }
   if (rc == -1)
-    return 0;
+    {
+      if (buff.iov_base) free(buff.iov_base);
+      return 0;
+    }

   for (next = buff.iov_base ; next < (char *)buff.iov_base + needed;
next += rtm->rtm_msglen)
     {
@@ -92,9 +98,13 @@ int arp_enumerate(void *parm, callback_t callback)
       sin2 = (struct sockaddr_inarp *)(rtm + 1);
       sdl = (struct sockaddr_dl *)((char *)sin2 + SA_SIZE(sin2));
       if (!callback.af_unspec(AF_INET, &sin2->sin_addr, LLADDR(sdl),
sdl->sdl_alen, parm))
-       return 0;
+        {
+          if (buff.iov_base) free(buff.iov_base);
+          return 0;
+        }
     }

+  if (buff.iov_base) free(buff.iov_base);
   return 1;
 }
 #endif /* defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) */


On Sun, 26 Apr 2026 at 19:18, Sagie Duchovne-Nave
<[email protected]> wrote:
>
> arp_enumerate() allocates a heap buffer via expand_buf() to hold the
> kernel ARP table dump retrieved through sysctl(NET_RT_FLAGS). This
> buffer is never freed on any return path -- neither the early error
> returns nor the normal return after iteration -- causing a leak on
> every call.
>
> The leak is most acute in the DHCPv6 path. get_client_mac() calls
> find_mac() up to five times per packet with lazy=0. Because the
> 'updated' flag is local to each find_mac() invocation, a cached
> ARP_EMPTY entry for an unresolvable IPv6 address does not short-
> circuit the kernel lookup: each call falls through to iface_enumerate()
> -> arp_enumerate(), leaking one buffer per call. This yields up to
> five leaked allocations per DHCPv6 SOLICIT packet. The leak size per
> call equals the full system-wide IPv4 ARP table dump across all
> interfaces.
>
> The condition is readily triggered by a DHCPv6 client whose MAC
> address cannot be resolved via NDP -- which is the common case on
> FreeBSD, because arp_enumerate() queries NET_RT_FLAGS/RTF_LLINFO,
> which returns IPv4 ARP entries only; IPv6 NDP neighbour entries are
> not included. As a result every IPv6 MAC lookup fails unconditionally
> on FreeBSD, every failed lookup produces an ARP_EMPTY record that is
> never promoted, and every subsequent packet for that client leaks five
> buffers.
>
> Fix: free buff.iov_base on all return paths in arp_enumerate(),
> including the early returns inside the retry loop where iov_base may
> already be non-NULL from a prior expand_buf() call.
>
> Reported against: FreeBSD 14, dnsmasq 2.91
> Observed symptom: steady process memory growth correlated with DHCPv6
> SOLICIT traffic from a client whose NDP entry is absent from the
> kernel table (confirmed by disabling the client stopping the balloon).
>
> Signed-off-by: Sagie D.
> ---
>  bpf.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/bpf.c b/bpf.c
> index XXXXXXX..XXXXXXX 100644
> --- a/bpf.c
> +++ b/bpf.c
> @@ -xx,12 +xx,18 @@ int arp_enumerate(void *parm, callback_t callback)
>    while (1)
>      {
>        if (!expand_buf(&buff, needed))
> -        return 0;
> +        {
> +          free(buff.iov_base);
> +          return 0;
> +        }
>        if ((rc = sysctl(mib, 6, buff.iov_base, &needed, NULL, 0)) == 0 ||
>            errno != ENOMEM)
>          break;
>        needed += needed / 8;
>      }
>    if (rc == -1)
> -    return 0;
> +    {
> +      free(buff.iov_base);
> +      return 0;
> +    }
>
>    for (next = buff.iov_base ; next < (char *)buff.iov_base + needed;
> next += rtm->rtm_msglen)
>      {
>        rtm = (struct rt_msghdr *)next;
>        sin2 = (struct sockaddr_inarp *)(rtm + 1);
>        sdl = (struct sockaddr_dl *)((char *)sin2 + SA_SIZE(sin2));
>        if (!callback.af_unspec(AF_INET, &sin2->sin_addr, LLADDR(sdl),
> sdl->sdl_alen, parm))
> -        return 0;
> +        {
> +          free(buff.iov_base);
> +          return 0;
> +        }
>      }
>
> -  return 1;
> +  free(buff.iov_base);
> +  return 1;
>  }

_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss