From bbe4537de3ef49c0d584896374876e5a3cdece75 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Sun, 17 May 2015 00:39:39 +0200 Subject: [PATCH] dnsmasq: again - latest upstream patches --- lfs/dnsmasq | 5 + .../0090-Tweak-EDNS-timeout-code.patch | 29 +++ ...hive-mailing-list-mirror-in-doc-html.patch | 27 +++ ...w-T1-and-T2-DHCPv4-options-to-be-set.patch | 200 ++++++++++++++++++ ...DHCP-context-for-PXE-proxy-server-id.patch | 29 +++ ...uffer-overflow-introduced-in-2-73rc6.patch | 49 +++++ 6 files changed, 339 insertions(+) create mode 100644 src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch create mode 100644 src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch create mode 100644 src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch create mode 100644 src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch create mode 100644 src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch diff --git a/lfs/dnsmasq b/lfs/dnsmasq index 7e6e849eb4..3dac04285a 100644 --- a/lfs/dnsmasq +++ b/lfs/dnsmasq @@ -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' \ diff --git a/src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch b/src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch new file mode 100644 index 0000000000..de1e0e6ef5 --- /dev/null +++ b/src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch @@ -0,0 +1,29 @@ +From 86fa1046920dedc8134136a6244ca96e8a37e9d8 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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 + diff --git a/src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch b/src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch new file mode 100644 index 0000000000..6ebfa81fb8 --- /dev/null +++ b/src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch @@ -0,0 +1,27 @@ +From 585840b03365372679907f175b07a01c9d621ae0 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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 + http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss 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 ++https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/. + You can contact me at simon@thekelleys.org.uk. + +-- +1.7.10.4 + diff --git a/src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch b/src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch new file mode 100644 index 0000000000..a0987679c8 --- /dev/null +++ b/src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch @@ -0,0 +1,200 @@ +From ca85a28241ef87919d68d52c843b6964b7070e11 Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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 + diff --git a/src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch b/src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch new file mode 100644 index 0000000000..64efd4f412 --- /dev/null +++ b/src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch @@ -0,0 +1,29 @@ +From 62018e1f720fa11e83879111a4b1b3753b5c25bb Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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 + diff --git a/src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch b/src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch new file mode 100644 index 0000000000..cb56c79cd3 --- /dev/null +++ b/src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch @@ -0,0 +1,49 @@ +From 5d07d77e75e0f02bc0a8f6029ffbc8b371fa804e Mon Sep 17 00:00:00 2001 +From: Simon Kelley +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/siz]. which is digs+6/7/8 chars */ +- namelen += digs+6; ++ /* output is \[x/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 + -- 2.39.2