]> git.ipfire.org Git - people/mfischer/ipfire-2.x.git/commitdiff
dnsmasq: again - latest upstream patches
authorMatthias Fischer <fischerm@ipfire.org>
Sat, 16 May 2015 22:39:39 +0000 (00:39 +0200)
committerMatthias Fischer <fischerm@ipfire.org>
Sat, 16 May 2015 22:39:39 +0000 (00:39 +0200)
lfs/dnsmasq
src/patches/dnsmasq/0090-Tweak-EDNS-timeout-code.patch [new file with mode: 0644]
src/patches/dnsmasq/0091-Pointer-to-mail-archive-mailing-list-mirror-in-doc-html.patch [new file with mode: 0644]
src/patches/dnsmasq/0092-Allow-T1-and-T2-DHCPv4-options-to-be-set.patch [new file with mode: 0644]
src/patches/dnsmasq/0093-Use-correct-DHCP-context-for-PXE-proxy-server-id.patch [new file with mode: 0644]
src/patches/dnsmasq/0094-Fix-buffer-overflow-introduced-in-2-73rc6.patch [new file with mode: 0644]

index 7e6e849eb49953c7164461be3e87e4e8d1142411..3dac04285a983f3df7e5b331750996209182ee8c 100644 (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' \
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 (file)
index 0000000..de1e0e6
--- /dev/null
@@ -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
+
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 (file)
index 0000000..6ebfa81
--- /dev/null
@@ -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
+
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 (file)
index 0000000..a098767
--- /dev/null
@@ -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
+
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 (file)
index 0000000..64efd4f
--- /dev/null
@@ -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
+
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 (file)
index 0000000..cb56c79
--- /dev/null
@@ -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
+