dnsmasq: again - latest upstream patches

This commit is contained in:
Matthias Fischer
2015-05-17 00:39:39 +02:00
parent 7cbd533265
commit bbe4537de3
6 changed files with 339 additions and 0 deletions

View File

@@ -162,6 +162,11 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0087-Constify-some-DHCP-lease-management-functions.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0088-Handle-UDP-packet-loss-when-fragmentation-of-large-packets-is-broken.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0089-Check-IPv4-mapped-IPv6-addresses-with--stop-rebind.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch
cd $(DIR_APP) && sed -i src/config.h \
-e 's|/\* #define HAVE_IDN \*/|#define HAVE_IDN|g' \

View File

@@ -0,0 +1,29 @@
From 86fa1046920dedc8134136a6244ca96e8a37e9d8 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Sun, 10 May 2015 13:50:59 +0100
Subject: [PATCH] Tweak EDNS timeout code.
---
src/forward.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/forward.c b/src/forward.c
index 592243f..74e5ab6 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -799,8 +799,10 @@ void reply_query(int fd, int family, time_t now)
}
/* We tried resending to this server with a smaller maximum size and got an answer.
- Make that permanent. */
- if (server && (forward->flags & FREC_TEST_PKTSZ))
+ Make that permanent. To avoid reduxing the packet size for an single dropped packet,
+ only do this when we get a truncated answer, or one larger than the safe size. */
+ if (server && (forward->flags & FREC_TEST_PKTSZ) &&
+ ((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
server->edns_pktsz = SAFE_PKTSZ;
/* If the answer is an error, keep the forward record in place in case
--
1.7.10.4

View File

@@ -0,0 +1,27 @@
From 585840b03365372679907f175b07a01c9d621ae0 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 13 May 2015 12:35:57 +0100
Subject: [PATCH] Pointer to mail-archive mailing list mirror in doc.html.
---
doc.html | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/doc.html b/doc.html
index 92c9d0d..54f59bb 100644
--- a/doc.html
+++ b/doc.html
@@ -74,7 +74,9 @@ for details.
There is a dnsmasq mailing list at <A
HREF="http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss">
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss</A> which should be the
-first location for queries, bugreports, suggestions etc.
+first location for queries, bugreports, suggestions etc. The list is mirrored, with a
+search facility, at <A HREF="https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/">
+https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/</A>.
You can contact me at <A
HREF="mailto:simon@thekelleys.org.uk">simon@thekelleys.org.uk</A>.
--
1.7.10.4

View File

@@ -0,0 +1,200 @@
From ca85a28241ef87919d68d52c843b6964b7070e11 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 13 May 2015 22:33:04 +0100
Subject: [PATCH] Allow T1 and T2 DHCPv4 options to be set.
---
CHANGELOG | 3 +++
dnsmasq.conf.example | 8 ++++++
src/dhcp-common.c | 4 +--
src/rfc2131.c | 71 +++++++++++++++++++++++++++++++++++---------------
4 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 94a521f..ef39a41 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -118,6 +118,9 @@ version 2.73
Check IPv4-mapped IPv6 addresses when --stop-rebind
is active. Thanks to Jordan Milne for spotting this.
+ Allow DHCPv4 options T1 and T2 to be set using --dhcp-option.
+ Thanks to Kevin Benton for patches and work on this.
+
version 2.72
Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
index 67be99a..1ae11df 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -345,6 +345,14 @@
# Ask client to poll for option changes every six hours. (RFC4242)
#dhcp-option=option6:information-refresh-time,6h
+# Set option 58 client renewal time (T1). Defaults to half of the
+# lease time if not specified. (RFC2132)
+#dhcp-option=option:T1:1m
+
+# Set option 59 rebinding time (T2). Defaults to 7/8 of the
+# lease time if not specified. (RFC2132)
+#dhcp-option=option:T2:2m
+
# Set the NTP time server address to be the same machine as
# is running dnsmasq
#dhcp-option=42,0.0.0.0
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index ce11520..bc48f41 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -545,8 +545,8 @@ static const struct opttab_t {
{ "parameter-request", 55, OT_INTERNAL },
{ "message", 56, OT_INTERNAL },
{ "max-message-size", 57, OT_INTERNAL },
- { "T1", 58, OT_INTERNAL | OT_TIME},
- { "T2", 59, OT_INTERNAL | OT_TIME},
+ { "T1", 58, OT_TIME},
+ { "T2", 59, OT_TIME},
{ "vendor-class", 60, 0 },
{ "client-id", 61, OT_INTERNAL },
{ "nis+-domain", 64, OT_NAME },
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 5552644..a10e499 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -52,7 +52,9 @@ static void do_options(struct dhcp_context *context,
int null_term, int pxearch,
unsigned char *uuid,
int vendor_class_len,
- time_t now);
+ time_t now,
+ unsigned int lease_time,
+ unsigned short fuzz);
static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
@@ -610,7 +612,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
clear_packet(mess, end);
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
- netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now);
+ netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0);
}
}
@@ -1042,13 +1044,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put(mess, end, OPTION_LEASE_TIME, 4, time);
/* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
- if (time != 0xffffffff)
- {
- option_put(mess, end, OPTION_T1, 4, (time/2));
- option_put(mess, end, OPTION_T2, 4, (time*7)/8);
- }
do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
return dhcp_packet_size(mess, agent_id, real_end);
@@ -1367,15 +1364,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
option_put(mess, end, OPTION_LEASE_TIME, 4, time);
- if (time != 0xffffffff)
- {
- while (fuzz > (time/16))
- fuzz = fuzz/2;
- option_put(mess, end, OPTION_T1, 4, (time/2) - fuzz);
- option_put(mess, end, OPTION_T2, 4, ((time/8)*7) - fuzz);
- }
do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
}
return dhcp_packet_size(mess, agent_id, real_end);
@@ -1440,7 +1430,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
}
do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
- netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
+ netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, 0xffffffff, 0);
*is_inform = 1; /* handle reply differently */
return dhcp_packet_size(mess, agent_id, real_end);
@@ -2137,7 +2127,9 @@ static void do_options(struct dhcp_context *context,
int null_term, int pxe_arch,
unsigned char *uuid,
int vendor_class_len,
- time_t now)
+ time_t now,
+ unsigned int lease_time,
+ unsigned short fuzz)
{
struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
struct dhcp_boot *boot;
@@ -2261,7 +2253,42 @@ static void do_options(struct dhcp_context *context,
/* rfc3011 says this doesn't need to be in the requested options list. */
if (subnet_addr.s_addr)
option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
-
+
+ if (lease_time != 0xffffffff)
+ {
+ unsigned int t1val = lease_time/2;
+ unsigned int t2val = (lease_time*7)/8;
+ unsigned int hval;
+
+ /* If set by user, sanity check, so not longer than lease. */
+ if ((opt = option_find2(OPTION_T1)))
+ {
+ hval = ntohl(*((unsigned int *)opt->val));
+ if (hval < lease_time && hval > 2)
+ t1val = hval;
+ }
+
+ if ((opt = option_find2(OPTION_T2)))
+ {
+ hval = ntohl(*((unsigned int *)opt->val));
+ if (hval < lease_time && hval > 2)
+ t2val = hval;
+ }
+
+ /* ensure T1 is still < T2 */
+ if (t2val <= t1val)
+ t1val = t2val - 1;
+
+ while (fuzz > (t1val/8))
+ fuzz = fuzz/2;
+
+ t1val -= fuzz;
+ t2val -= fuzz;
+
+ option_put(mess, end, OPTION_T1, 4, t1val);
+ option_put(mess, end, OPTION_T2, 4, t2val);
+ }
+
/* replies to DHCPINFORM may not have a valid context */
if (context)
{
@@ -2356,12 +2383,14 @@ static void do_options(struct dhcp_context *context,
if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno))
continue;
- /* prohibit some used-internally options */
+ /* prohibit some used-internally options. T1 and T2 already handled. */
if (optno == OPTION_CLIENT_FQDN ||
optno == OPTION_MAXMESSAGE ||
optno == OPTION_OVERLOAD ||
optno == OPTION_PAD ||
- optno == OPTION_END)
+ optno == OPTION_END ||
+ optno == OPTION_T1 ||
+ optno == OPTION_T2)
continue;
if (optno == OPTION_SNAME && done_server)
--
1.7.10.4

View File

@@ -0,0 +1,29 @@
From 62018e1f720fa11e83879111a4b1b3753b5c25bb Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Thu, 14 May 2015 21:30:00 +0100
Subject: [PATCH] Use correct DHCP context for PXE-proxy server-id.
---
src/rfc2131.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/rfc2131.c b/src/rfc2131.c
index b95f9be..70d1e59 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -888,10 +888,10 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
- option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
+ option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(tmp->local.s_addr));
pxe_misc(mess, end, uuid);
prune_vendor_opts(tagif_netid);
- do_encap_opts(pxe_opts(pxearch, tagif_netid, context->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
+ do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
log_tags(tagif_netid, ntohl(mess->xid));
--
1.7.10.4

View File

@@ -0,0 +1,49 @@
From 5d07d77e75e0f02bc0a8f6029ffbc8b371fa804e Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 15 May 2015 18:13:06 +0100
Subject: [PATCH] Fix buffer overflow introduced in 2.73rc6.
Fix off-by-one in code which checks for over-long domain names
in received DNS packets. This enables buffer overflow attacks
which can certainly crash dnsmasq and may allow for arbitrary
code execution. The problem was introduced in commit b8f16556d,
release 2.73rc6, so has not escaped into any stable release.
Note that the off-by-one was in the label length determination,
so the buffer can be overflowed by as many bytes as there are
labels in the name - ie, many.
Thanks to Ron Bowes, who used lcmatuf's afl-fuzz tool to find
the problem.
---
src/rfc1035.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 5e3f566..a95241f 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -94,8 +94,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
count = 256;
digs = ((count-1)>>2)+1;
- /* output is \[x<hex>/siz]. which is digs+6/7/8 chars */
- namelen += digs+6;
+ /* output is \[x<hex>/siz]. which is digs+7/8/9 chars */
+ namelen += digs+7;
if (count > 9)
namelen++;
if (count > 99)
@@ -125,8 +125,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
}
else
{ /* label_type = 0 -> label. */
- namelen += l;
- if (namelen+1 >= MAXDNAME)
+ namelen += l + 1; /* include period */
+ if (namelen >= MAXDNAME)
return 0;
if (!CHECK_LEN(header, p, plen, l))
return 0;
--
1.7.10.4