diff --git a/CHANGELOG b/CHANGELOG index 0559a6f..59c9c49 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,12 @@ version 2.77 Thanks to Mozilla for funding the security audit which spotted this bug. + Fix logic error in Linux netlink code. This could + cause dnsmasq to enter a tight loop on systems + with a very large number of network interfaces. + Thanks to Ivan Kokshaysky for the diagnosis and + patch. + version 2.76 Include 0.0.0.0/8 in DNS rebind checks. This range diff --git a/src/netlink.c b/src/netlink.c index 049247b..8cd51af 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -188,11 +188,17 @@ int iface_enumerate(int family, void *parm, int (*callback)()) } for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len)) - if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR) + if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR) { /* May be multicast arriving async */ nl_async(h); } + else if (h->nlmsg_seq != seq) + { + /* May be part of incomplete response to previous request after + ENOBUFS. Drop it. */ + continue; + } else if (h->nlmsg_type == NLMSG_DONE) return callback_ok; else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)