dnsmasq: Handle memory allocation failure from upstream

This commit is contained in:
coolsnowwolf 2018-09-23 14:55:59 +08:00
parent 121e1f8047
commit 4622c6891a
6 changed files with 108 additions and 136 deletions

View File

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_VERSION:=2.80test3
PKG_RELEASE:=1
PKG_VERSION:=2.80test6
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/test-releases
PKG_HASH:=af9f6fd13e0d6c5a68059bcf8634c2784c0533017fd48fbaf59cd2955342d301
PKG_HASH:=aa74384f4ee6941d7785db79cf50fd6399cb992d219fc07ea6affeabe63b0190
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
@ -53,6 +53,7 @@ $(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS+=@IPV6
VARIANT:=dhcpv6
PROVIDES:=dnsmasq
endef
define Package/dnsmasq-full
@ -62,6 +63,7 @@ $(call Package/dnsmasq/Default)
+PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \
+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack
VARIANT:=full
PROVIDES:=dnsmasq
endef
define Package/dnsmasq/description
@ -122,7 +124,8 @@ Package/dnsmasq-full/conffiles = $(Package/dnsmasq/conffiles)
TARGET_CFLAGS += -ffunction-sections -fdata-sections
TARGET_LDFLAGS += -Wl,--gc-sections
COPTS = $(if $(CONFIG_IPV6),,-DNO_IPV6)
COPTS = -DHAVE_UBUS \
$(if $(CONFIG_IPV6),,-DNO_IPV6)
ifeq ($(BUILD_VARIANT),nodhcpv6)
COPTS += -DNO_DHCP6

View File

@ -813,6 +813,7 @@ dnsmasq_start()
append_bool "$cfg" localise_queries "--localise-queries"
append_bool "$cfg" readethers "--read-ethers"
append_bool "$cfg" dbus "--enable-dbus"
append_bool "$cfg" ubus "--enable-ubus" 1
append_bool "$cfg" expandhosts "--expand-hosts"
config_get tftp_root "$cfg" "tftp_root"
[ -n "$tftp_root" ] && mkdir -p "$tftp_root" && append_bool "$cfg" enable_tftp "--enable-tftp"
@ -869,9 +870,6 @@ dnsmasq_start()
ADD_LOCAL_FQDN="$ADD_LOCAL_HOSTNAME"
fi
config_get_bool readethers "$cfg" readethers
[ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
config_get user_dhcpscript $cfg dhcpscript
if has_handler || [ -n "$user_dhcpscript" ]; then
xappend "--dhcp-script=$DHCPSCRIPT"

View File

@ -0,0 +1,45 @@
From ea6cc338042094f8023d224e53c244da158e6499 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Tue, 18 Sep 2018 23:21:17 +0100
Subject: [PATCH] Handle memory allocation failure in make_non_terminals()
Thanks to Kristian Evensen for spotting the problem.
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
---
src/cache.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- a/src/cache.c
+++ b/src/cache.c
@@ -1360,7 +1360,7 @@ void cache_add_dhcp_entry(char *host_nam
static void make_non_terminals(struct crec *source)
{
char *name = cache_get_name(source);
- struct crec* crecp, *tmp, **up;
+ struct crec *crecp, *tmp, **up;
int type = F_HOSTS | F_CONFIG;
#ifdef HAVE_DHCP
if (source->flags & F_DHCP)
@@ -1434,12 +1434,15 @@ static void make_non_terminals(struct cr
#endif
crecp = whine_malloc(sizeof(struct crec));
- *crecp = *source;
- crecp->flags &= ~(F_IPV4 | F_IPV6 | F_CNAME | F_DNSKEY | F_DS | F_REVERSE);
- crecp->flags |= F_NAMEP;
- crecp->name.namep = name;
-
- cache_hash(crecp);
+ if (crecp)
+ {
+ *crecp = *source;
+ crecp->flags &= ~(F_IPV4 | F_IPV6 | F_CNAME | F_DNSKEY | F_DS | F_REVERSE);
+ crecp->flags |= F_NAMEP;
+ crecp->name.namep = name;
+
+ cache_hash(crecp);
+ }
}
}

View File

@ -0,0 +1,54 @@
From 4139298d287eb5c57f4aa53c459cb02fc5be2495 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 19 Sep 2018 22:27:11 +0100
Subject: [PATCH 2/2] Change behavior when RD bit unset in queries.
Change anti cache-snooping behaviour with queries with the
recursion-desired bit unset. Instead to returning SERVFAIL, we
now always forward, and never answer from the cache. This
allows "dig +trace" command to work.
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
---
CHANGELOG | 7 ++++++-
src/rfc1035.c | 8 +++-----
2 files changed, 9 insertions(+), 6 deletions(-)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -59,7 +59,12 @@ version 2.80
Returning null addresses is a useful technique for ad-blocking.
Thanks to Peter Russell for the suggestion.
-
+ Change anti cache-snooping behaviour with queries with the
+ recursion-desired bit unset. Instead to returning SERVFAIL, we
+ now always forward, and never answer from the cache. This
+ allows "dig +trace" command to work.
+
+
version 2.79
Fix parsing of CNAME arguments, which are confused by extra spaces.
Thanks to Diego Aguirre for spotting the bug.
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1293,16 +1293,14 @@ size_t answer_request(struct dns_header
struct mx_srv_record *rec;
size_t len;
- if (ntohs(header->ancount) != 0 ||
+ /* never answer queries with RD unset, to avoid cache snooping. */
+ if (!(header->hb3 & HB3_RD) ||
+ ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 ||
ntohs(header->qdcount) == 0 ||
OPCODE(header) != QUERY )
return 0;
- /* always servfail queries with RD unset, to avoid cache snooping. */
- if (!(header->hb3 & HB3_RD))
- return setup_reply(header, qlen, NULL, F_SERVFAIL, 0);
-
/* Don't return AD set if checking disabled. */
if (header->hb4 & HB4_CD)
sec_data = 0;

View File

@ -7,7 +7,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -88,7 +88,7 @@ typedef unsigned long long u64;
@@ -95,7 +95,7 @@ typedef unsigned long long u64;
#if defined(HAVE_SOLARIS_NETWORK)
# include <sys/sockio.h>
#endif

View File

@ -1,128 +0,0 @@
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -19,6 +19,8 @@
#include "dnsmasq.h"
+#include <libubus.h>
+
struct daemon *daemon;
static volatile pid_t pid = 0;
@@ -32,6 +34,64 @@ static void fatal_event(struct event_des
static int read_event(int fd, struct event_desc *evp, char **msg);
static void poll_resolv(int force, int do_reload, time_t now);
+static struct ubus_context *ubus;
+static struct blob_buf b;
+
+static struct ubus_object_type ubus_object_type = {
+ .name = "dnsmasq",
+};
+
+static struct ubus_object ubus_object = {
+ .name = "dnsmasq",
+ .type = &ubus_object_type,
+};
+
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
+{
+ if (!ubus || !ubus_object.has_subscribers)
+ return;
+
+ blob_buf_init(&b, 0);
+ if (mac)
+ blobmsg_add_string(&b, "mac", mac);
+ if (ip)
+ blobmsg_add_string(&b, "ip", ip);
+ if (name)
+ blobmsg_add_string(&b, "name", name);
+ if (interface)
+ blobmsg_add_string(&b, "interface", interface);
+ ubus_notify(ubus, &ubus_object, type, b.head, -1);
+}
+
+static void set_ubus_listeners(void)
+{
+ if (!ubus)
+ return;
+
+ poll_listen(ubus->sock.fd, POLLIN);
+ poll_listen(ubus->sock.fd, POLLERR);
+ poll_listen(ubus->sock.fd, POLLHUP);
+}
+
+static void check_ubus_listeners()
+{
+ if (!ubus) {
+ ubus = ubus_connect(NULL);
+ if (ubus)
+ ubus_add_object(ubus, &ubus_object);
+ else
+ return;
+ }
+
+ if (poll_check(ubus->sock.fd, POLLIN))
+ ubus_handle_event(ubus);
+
+ if (poll_check(ubus->sock.fd, POLLHUP)) {
+ ubus_free(ubus);
+ ubus = NULL;
+ }
+}
+
int main (int argc, char **argv)
{
int bind_fallback = 0;
@@ -949,6 +1009,7 @@ int main (int argc, char **argv)
set_dbus_listeners();
#endif
+ set_ubus_listeners();
#ifdef HAVE_DHCP
if (daemon->dhcp || daemon->relay4)
{
@@ -1079,6 +1140,8 @@ int main (int argc, char **argv)
check_dbus_listeners();
#endif
+ check_ubus_listeners();
+
check_dns_listeners(now);
#ifdef HAVE_TFTP
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@ all : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) -lubox -lubus" \
-f $(top)/Makefile dnsmasq
mostly_clean :
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1445,6 +1445,8 @@ void emit_dbus_signal(int action, struct
# endif
#endif
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface);
+
/* ipset.c */
#ifdef HAVE_IPSET
void ipset_init(void);
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -1636,6 +1636,10 @@ static void log_packet(char *type, void
daemon->namebuff,
string ? string : "",
err ? err : "");
+ if (!strcmp(type, "DHCPACK"))
+ ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
+ else if (!strcmp(type, "DHCPRELEASE"))
+ ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface);
}
static void log_options(unsigned char *start, u32 xid)