dnsmasq: include latest patches
authorKevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Fri, 25 Feb 2022 10:54:40 +0000 (10:54 +0000)
committerKevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Sun, 24 Apr 2022 08:18:55 +0000 (09:18 +0100)
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
package/network/services/dnsmasq/patches/0001-Fix-missing-reverse-records-from-dynamic-host.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0002-Fix-longjump-compiler-warnings.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0003-Fix-memory-leak-when-DBUS-connection-fails.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0004-Update-German-translation.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0005-Enhance-domain-to-accept-interface-names-for-the-add.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0006-Manpage-update-for-localise-queries.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0007-Add-DNSMASQ_DATA_MISSING-envvar-to-lease-change-scri.patch [new file with mode: 0644]
package/network/services/dnsmasq/patches/0008-Fix-write-after-free-error-in-DHCPv6-code.-CVE-2022-.patch [new file with mode: 0644]

diff --git a/package/network/services/dnsmasq/patches/0001-Fix-missing-reverse-records-from-dynamic-host.patch b/package/network/services/dnsmasq/patches/0001-Fix-missing-reverse-records-from-dynamic-host.patch
new file mode 100644 (file)
index 0000000..7d45cd8
--- /dev/null
@@ -0,0 +1,35 @@
+From f4c87b504b444efb05892b8c7fc295e886f70789 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Fri, 18 Feb 2022 20:53:56 +0000
+Subject: [PATCH 1/8] Fix missing reverse-records from --dynamic-host.
+
+Thanks to Sten Spans for spotting the bug.
+---
+ src/rfc1035.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/rfc1035.c b/src/rfc1035.c
+index 34eaf0a..60ef272 100644
+--- a/src/rfc1035.c
++++ b/src/rfc1035.c
+@@ -1597,7 +1597,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
+                   
+                   if (addrlist)
+                     break;
+-                  else
++                  else if (!(intr->flags & INP4))
+                     while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
+                       intr = intr->next;
+                 }
+@@ -1612,7 +1612,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
+                   
+                   if (addrlist)
+                     break;
+-                  else
++                  else if (!(intr->flags & INP6))
+                     while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
+                       intr = intr->next;
+                 }
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0002-Fix-longjump-compiler-warnings.patch b/package/network/services/dnsmasq/patches/0002-Fix-longjump-compiler-warnings.patch
new file mode 100644 (file)
index 0000000..97da691
--- /dev/null
@@ -0,0 +1,112 @@
+From bb6f6bae0ba6a95f481485f9d74a89072f2c800c Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 22 Feb 2022 21:56:48 +0000
+Subject: [PATCH 2/8] Fix longjump() compiler warnings.
+
+---
+ src/option.c | 36 +++++++++++++++---------------------
+ 1 file changed, 15 insertions(+), 21 deletions(-)
+
+diff --git a/src/option.c b/src/option.c
+index d9dd6a3..c354ddf 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -4974,26 +4974,20 @@ err:
+   return 1;
+ }
+-static void read_file(char *file, FILE *f, int hard_opt)      
++static void read_file(char *file, FILE *f, int hard_opt, int from_script)     
+ {
+   volatile int lineno = 0;
+   char *buff = daemon->namebuff;
+   
+   while (fgets(buff, MAXDNAME, f))
+     {
+-      int white, i, script = 0;
++      int white, i;
+       volatile int option;
+       char *errmess, *p, *arg, *start;
+       size_t len;
+-      if (hard_opt == LOPT_CONF_SCRIPT)
+-      {
+-        hard_opt = 0;
+-        script = 1;
+-      }
+-      
+       option = (hard_opt == LOPT_REV_SERV) ? 0 : hard_opt;
+- 
++
+       /* Memory allocation failure longjmps here if mem_recover == 1 */ 
+       if (option != 0 || hard_opt == LOPT_REV_SERV)
+       {
+@@ -5001,7 +4995,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
+           continue;
+         mem_recover = 1;
+       }
+-      
++
+       arg = NULL;
+       lineno++;
+       errmess = NULL;
+@@ -5107,7 +5101,7 @@ static void read_file(char *file, FILE *f, int hard_opt)
+         
+       if (errmess || !one_opt(option, arg, daemon->namebuff, _("error"), 0, hard_opt == LOPT_REV_SERV))
+       {
+-        if (script)
++        if (from_script)
+           sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" in output from %s"), file);
+         else
+           sprintf(daemon->namebuff + strlen(daemon->namebuff), _(" at line %d of %s"), lineno, file);
+@@ -5153,8 +5147,14 @@ static int one_file(char *file, int hard_opt)
+       hard_opt = 0;
+       nofile_ok = 1;
+     }
+-  
+-  if (hard_opt == 0 && strcmp(file, "-") == 0)
++
++   if (hard_opt == LOPT_CONF_SCRIPT)
++     {
++       hard_opt = 0;
++       do_popen = 1;
++     }
++   
++   if (hard_opt == 0 && !do_popen && strcmp(file, "-") == 0)
+     {
+       if (read_stdin == 1)
+       return 1;
+@@ -5167,12 +5167,6 @@ static int one_file(char *file, int hard_opt)
+       /* ignore repeated files. */
+       struct stat statbuf;
+     
+-      if (hard_opt == LOPT_CONF_SCRIPT)
+-      {
+-        hard_opt = 0;
+-        do_popen = 1;
+-      }
+-      
+       if (hard_opt == 0 && stat(file, &statbuf) == 0)
+       {
+         struct fileread *r;
+@@ -5211,7 +5205,7 @@ static int one_file(char *file, int hard_opt)
+       } 
+     }
+   
+-  read_file(file, f, do_popen ? LOPT_CONF_SCRIPT : hard_opt);
++   read_file(file, f, hard_opt, do_popen);
+   if (do_popen)
+     {
+@@ -5365,7 +5359,7 @@ void read_servers_file(void)
+     }
+   
+   mark_servers(SERV_FROM_FILE);
+-  read_file(daemon->servers_file, f, LOPT_REV_SERV);
++  read_file(daemon->servers_file, f, LOPT_REV_SERV, 0);
+   fclose(f);
+   cleanup_servers();
+   check_servers(0);
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0003-Fix-memory-leak-when-DBUS-connection-fails.patch b/package/network/services/dnsmasq/patches/0003-Fix-memory-leak-when-DBUS-connection-fails.patch
new file mode 100644 (file)
index 0000000..526b2ff
--- /dev/null
@@ -0,0 +1,30 @@
+From c27cfeaa7b9bfa09b347f3f26390af39177190db Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 24 Feb 2022 23:18:54 +0000
+Subject: [PATCH 3/8] Fix memory leak when DBUS connection fails.
+
+---
+ src/dbus.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index 0c55ea5..bf6b661 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -761,8 +761,11 @@ char *dbus_init(void)
+   dbus_error_init (&dbus_error);
+   if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error)))
+-    return NULL;
+-    
++    {
++      dbus_error_free(&dbus_error);
++      return NULL;
++    }
++  
+   dbus_connection_set_exit_on_disconnect(connection, FALSE);
+   dbus_connection_set_watch_functions(connection, add_watch, remove_watch, 
+                                     NULL, NULL, NULL);
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0004-Update-German-translation.patch b/package/network/services/dnsmasq/patches/0004-Update-German-translation.patch
new file mode 100644 (file)
index 0000000..efa560a
--- /dev/null
@@ -0,0 +1,353 @@
+From b7f62475d03336c5c58d633fc795894896c33b1f Mon Sep 17 00:00:00 2001
+From: Conrad Kostecki <ck@conrad-kostecki.de>
+Date: Wed, 2 Mar 2022 19:28:26 +0000
+Subject: [PATCH 4/8] Update German translation.
+
+---
+ po/de.po | 110 ++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 52 insertions(+), 58 deletions(-)
+
+diff --git a/po/de.po b/po/de.po
+index 1f1c058..7173712 100644
+--- a/po/de.po
++++ b/po/de.po
+@@ -2,7 +2,7 @@
+ #
+ # This revised version is (C) Copyright by
+ # Matthias Andree <matthias.andree@gmx.de>, 2010 - 2021.
+-# Conrad Kostecki <ck@conrad-kostecki.de>, 2014 - 2020.
++# Conrad Kostecki <conrad@kostecki.com>, 2014 - 2022.
+ # It is subject to the GNU General Public License v2,
+ # or at your option, any later version.
+ #
+@@ -10,17 +10,18 @@
+ # Simon Kelley <simon@thekelleys.org.uk>, 2005.
+ msgid ""
+ msgstr ""
+-"Project-Id-Version: dnsmasq 2.85rc2\n"
++"Project-Id-Version: dnsmasq 2.87test8\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2021-03-20 00:00+0000\n"
+-"PO-Revision-Date: 2021-03-27 15:30+0100\n"
+-"Last-Translator: Matthias Andree <matthias.andree@gmx.de>\n"
++"PO-Revision-Date: 2022-02-28 14:49+0100\n"
++"Last-Translator: Conrad Kostecki <conrad@kostecki.com>\n"
+ "Language-Team: German <de@li.org>\n"
+ "Language: de\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
++"X-Generator: Poedit 3.0.1\n"
+ #: cache.c:572
+ msgid "Internal error in cache."
+@@ -243,7 +244,7 @@ msgstr "RFC3993 \"subscriber-id\" auf Marke abbilden."
+ #: option.c:400
+ msgid "Specify vendor class to match for PXE requests."
+-msgstr "Herstellerklasse für Vergleich von PXE-Anforderungen angeben"
++msgstr "Herstellerklasse für Vergleich von PXE-Anforderungen angeben."
+ #: option.c:401
+ msgid "Don't do DHCP for hosts with tag set."
+@@ -726,11 +727,11 @@ msgstr "Spezifiziere IPSets, zu denen passende Domains hinzugefügt werden solle
+ #: option.c:517
+ msgid "Enable filtering of DNS queries with connection-track marks."
+-msgstr ""
++msgstr "Aktivieren Sie das Filtern von DNS-Abfragen mit \"connection-track\"-Markierungen."
+ #: option.c:518
+ msgid "Set allowed DNS patterns for a connection-track mark."
+-msgstr ""
++msgstr "Legen Sie zulässige DNS-Muster für eine \"connection-track\"-Markierung fest."
+ #: option.c:519
+ msgid "Specify a domain and address range for synthesised names"
+@@ -819,12 +820,11 @@ msgstr "Rufe dhcp-script auf, wenn der Ablauf des Leases sich ändert."
+ #: option.c:540
+ msgid "Send Cisco Umbrella identifiers including remote IP."
+-msgstr ""
++msgstr "Senden Sie Cisco Umbrella-Identifikatoren einschließlich der Remote-IP."
+ #: option.c:541
+-#, fuzzy
+ msgid "Do not log routine TFTP."
+-msgstr "Protokolliere kein Routine-DHCP."
++msgstr "Protokolliere kein Routine-TFTP."
+ #: option.c:771
+ #, c-format
+@@ -867,11 +867,11 @@ msgstr "Fehlerhafter Schnittestellenname"
+ #: option.c:1192
+ msgid "inappropriate vendor:"
+-msgstr ""
++msgstr "Ungeeigneter Anbieter:"
+ #: option.c:1199
+ msgid "inappropriate encap:"
+-msgstr ""
++msgstr "Ungeeignete Kapselung:"
+ #: option.c:1225
+ msgid "unsupported encapsulation for IPv6 option"
+@@ -952,28 +952,24 @@ msgid "recompile with HAVE_LUASCRIPT defined to enable Lua scripts"
+ msgstr "Neuübersetzung mit HAVE_LUASCRIPT nötig, um benutzerdefinierte Lua-Skripte auszuführen"
+ #: option.c:2291 option.c:2327
+-#, fuzzy
+ msgid "bad prefix length"
+-msgstr "fehlerhaftes Präfix"
++msgstr "fehlerhafte Präfixlänge"
+ #: option.c:2303 option.c:2348 option.c:2398
+ msgid "bad prefix"
+ msgstr "fehlerhaftes Präfix"
+ #: option.c:2418
+-#, fuzzy
+ msgid "prefix length too small"
+-msgstr "Die Präfixlänge muss mindestens 64 sein"
++msgstr "Präfixlänge ist zu klein"
+ #: option.c:2697
+-#, fuzzy
+ msgid "Bad address in --address"
+-msgstr "Adresse in Gebrauch"
++msgstr "Fehlerhafte Adresse in --address"
+ #: option.c:2751
+-#, fuzzy
+ msgid "bad IPv4 prefix"
+-msgstr "fehlerhaftes IPv6-Präfix"
++msgstr "fehlerhaftes IPv4-Präfix"
+ #: option.c:2756 option.c:3569
+ msgid "bad IPv6 prefix"
+@@ -984,9 +980,8 @@ msgid "recompile with HAVE_IPSET defined to enable ipset directives"
+ msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
+ #: option.c:2843 option.c:2861
+-#, fuzzy
+ msgid "recompile with HAVE_CONNTRACK defined to enable connmark-allowlist directives"
+-msgstr "Neuübersetzung mit HAVE_IPSET nötig, um IPSet-Direktiven zu aktivieren"
++msgstr "Neukompilierung mit HAVE_CONNTRACK notwendig, um connmark-allowlist-Direktiven zu aktivieren"
+ #: option.c:3119
+ msgid "bad port range"
+@@ -1131,7 +1126,7 @@ msgstr "unzulässige Wichtung"
+ #: option.c:4661
+ msgid "Bad host-record"
+-msgstr "fehlerhafter \"host-record\""
++msgstr "Fehlerhafter \"host-record\""
+ #: option.c:4700
+ msgid "Bad name in host-record"
+@@ -1314,9 +1309,9 @@ msgid "Maximum number of concurrent DNS queries reached (max: %d)"
+ msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
+ #: forward.c:2496
+-#, fuzzy, c-format
++#, c-format
+ msgid "Maximum number of concurrent DNS queries to %s reached (max: %d)"
+-msgstr "Höchstzahl an nebenläufiger DNS-Anfragen erreicht (max. %d)"
++msgstr "Maximale Anzahl gleichzeitiger DNS-Abfragen, die erreicht %s (max. %d)"
+ #: network.c:670
+ #, c-format
+@@ -1403,9 +1398,9 @@ msgid "domain"
+ msgstr "Domäne"
+ #: network.c:1607
+-#, fuzzy, c-format
++#, c-format
+ msgid "using nameserver %s#%d for %s %s%s %s"
+-msgstr "Benutze Namensserver %s#%d für %s %s %s"
++msgstr "benutze Namensserver %s#%d für %s %s %s %s"
+ #: network.c:1611
+ #, c-format
+@@ -1423,14 +1418,14 @@ msgid "using nameserver %s#%d"
+ msgstr "Benutze Namensserver %s#%d"
+ #: network.c:1630
+-#, fuzzy, c-format
++#, c-format
+ msgid "using only locally-known addresses for %s"
+-msgstr "Benutze nur lokal-bekannte Adressen für %s %s"
++msgstr "benutze nur lokal-bekannte Adressen für %s"
+ #: network.c:1633
+-#, fuzzy, c-format
++#, c-format
+ msgid "using standard nameservers for %s"
+-msgstr "Benutze standard Namensserver für %s %s"
++msgstr "benutze standard Namensserver für %s"
+ #: network.c:1637
+ #, c-format
+@@ -1534,9 +1529,9 @@ msgid "DBus not available: set HAVE_DBUS in src/config.h"
+ msgstr "DBus nicht verfügbar: setzen Sie HAVE_DBUS in src/config.h"
+ #: dnsmasq.c:456 dnsmasq.c:1228
+-#, fuzzy, c-format
++#, c-format
+ msgid "UBus error: %s"
+-msgstr "DBus-Fehler: %s"
++msgstr "UBus-Fehler: %s"
+ #: dnsmasq.c:459
+ msgid "UBus not available: set HAVE_UBUS in src/config.h"
+@@ -1696,9 +1691,8 @@ msgid "connected to system DBus"
+ msgstr "Mit System-DBus verbunden"
+ #: dnsmasq.c:1225
+-#, fuzzy
+ msgid "connected to system UBus"
+-msgstr "Mit System-UBus verbunden"
++msgstr "mit System-UBus verbunden"
+ #: dnsmasq.c:1391
+ #, c-format
+@@ -2151,7 +2145,7 @@ msgstr "Datei %s nicht gefunden für %s"
+ #: tftp.c:602
+ #, c-format
+ msgid "ignoring packet from %s (TID mismatch)"
+-msgstr ""
++msgstr "Paket von %s wird ignoriert (TID-Nichtübereinstimmung)"
+ #: tftp.c:646
+ #, c-format
+@@ -2378,95 +2372,95 @@ msgstr "Aktualisierung von ipset %s fehlgeschlagen: %s"
+ #: pattern.c:29
+ #, c-format
+ msgid "[pattern.c:%d] Assertion failure: %s"
+-msgstr ""
++msgstr "[pattern.c:%d] Assertion failure: %s"
+ #: pattern.c:142
+ #, c-format
+ msgid "Invalid DNS name: Invalid character %c."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Ungültiges Zeichen %c."
+ #: pattern.c:151
+ msgid "Invalid DNS name: Empty label."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Leeres Label."
+ #: pattern.c:156
+ msgid "Invalid DNS name: Label starts with hyphen."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Label beginnt mit Bindestrich."
+ #: pattern.c:170
+ msgid "Invalid DNS name: Label ends with hyphen."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Bezeichnung endet mit Bindestrich."
+ #: pattern.c:176
+ #, c-format
+ msgid "Invalid DNS name: Label is too long (%zu)."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Label ist zu lang (%zu)."
+ #: pattern.c:184
+ #, c-format
+ msgid "Invalid DNS name: Not enough labels (%zu)."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Nicht genügend Labels (%zu)."
+ #: pattern.c:189
+ msgid "Invalid DNS name: Final label is fully numeric."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: Das endgültige Label ist vollständig numerisch."
+ #: pattern.c:199
+ msgid "Invalid DNS name: \"local\" pseudo-TLD."
+-msgstr ""
++msgstr "Ungültiger DNS-Name: \"lokale\" Pseudo-TLD."
+ #: pattern.c:204
+ #, c-format
+ msgid "DNS name has invalid length (%zu)."
+-msgstr ""
++msgstr "Der DNS-Name hat eine ungültige Länge (%zu)."
+ #: pattern.c:258
+ #, c-format
+ msgid "Invalid DNS name pattern: Invalid character %c."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Ungültiges Zeichen %c."
+ #: pattern.c:267
+ msgid "Invalid DNS name pattern: Empty label."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Leeres Label."
+ #: pattern.c:272
+ msgid "Invalid DNS name pattern: Label starts with hyphen."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Bezeichnung beginnt mit Bindestrich."
+ #: pattern.c:285
+ msgid "Invalid DNS name pattern: Wildcard character used more than twice per label."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Platzhalterzeichen werden mehr als zweimal pro Label verwendet."
+ #: pattern.c:295
+ msgid "Invalid DNS name pattern: Label ends with hyphen."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Bezeichnung endet mit Bindestrich."
+ #: pattern.c:301
+ #, c-format
+ msgid "Invalid DNS name pattern: Label is too long (%zu)."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Label ist zu lang (%zu)."
+ #: pattern.c:309
+ #, c-format
+ msgid "Invalid DNS name pattern: Not enough labels (%zu)."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Nicht genügend Labels (%zu)."
+ #: pattern.c:314
+ msgid "Invalid DNS name pattern: Wildcard within final two labels."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Platzhalter innerhalb der letzten beiden Labels."
+ #: pattern.c:319
+ msgid "Invalid DNS name pattern: Final label is fully numeric."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: Das endgültige Label ist vollständig numerisch."
+ #: pattern.c:329
+ msgid "Invalid DNS name pattern: \"local\" pseudo-TLD."
+-msgstr ""
++msgstr "Ungültiges DNS-Namensmuster: \"lokale\" Pseudo-TLD."
+ #: pattern.c:334
+ #, c-format
+ msgid "DNS name pattern has invalid length after removing wildcards (%zu)."
+-msgstr ""
++msgstr "Das DNS-Namensmuster hat nach dem Entfernen von Platzhaltern (%zu) eine ungültige Länge."
+ #: dnssec.c:206
+ msgid "system time considered valid, now checking DNSSEC signature timestamps."
+@@ -2600,7 +2594,7 @@ msgstr "Von System-UBus trennen"
+ #: ubus.c:179 ubus.c:326
+ #, c-format
+ msgid "UBus command failed: %d (%s)"
+-msgstr ""
++msgstr "UBus-Befehl fehlgeschlagen: %d (%s)"
+ #: hash-questions.c:40
+ msgid "Failed to create SHA-256 hash object"
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0005-Enhance-domain-to-accept-interface-names-for-the-add.patch b/package/network/services/dnsmasq/patches/0005-Enhance-domain-to-accept-interface-names-for-the-add.patch
new file mode 100644 (file)
index 0000000..e884b7e
--- /dev/null
@@ -0,0 +1,237 @@
+From 3ab6dd1c37da3f4ea0e369a1ecdf275697f01ecc Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sat, 5 Mar 2022 18:07:07 +0000
+Subject: [PATCH 5/8] Enhance --domain to accept, interface names for the
+ address range.
+
+This allows hosts get a domain which relects the interface they
+are attached to in a way which doesn't require hard-coding addresses.
+
+Thanks to Sten Spans for the idea.
+---
+ CHANGELOG     |  6 ++++++
+ man/dnsmasq.8 |  7 ++++++-
+ src/dnsmasq.h |  2 ++
+ src/domain.c  | 31 ++++++++++++++++++++++++-------
+ src/network.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ src/option.c  | 10 ++++++++--
+ 6 files changed, 92 insertions(+), 11 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index e6fe8fd..87d6c2b 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -49,6 +49,12 @@ version 2.87
+       Add --conf-script configuration option.
++      Enhance --domain to accept, for instance,
++      --domain=net2.thekelleys.org.uk,eth2 so that hosts get a domain
++      which relects the interface they are attached to in a way which
++      doesn't require hard-coding addresses. Thanks to Sten Spans for
++      the idea.
++
+       
+ version 2.86
+       Handle DHCPREBIND requests in the DHCPv6 server code.
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index ca155f0..f68a286 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -1935,7 +1935,7 @@ is the address of the relay and the second, as before, specifies an extra subnet
+ addresses may be allocated from.
+ .TP
+-.B \-s, --domain=<domain>[,<address range>[,local]]
++.B \-s, --domain=<domain>[[,<address range>[,local]]|<interface>]
+ Specifies DNS domains for the DHCP server. Domains may be be given 
+ unconditionally (without the IP range) or for limited IP ranges. This has two effects;
+ firstly it causes the DHCP server to return the domain to any hosts
+@@ -1969,6 +1969,11 @@ additional flag "local" may be supplied which has the effect of adding
+ is identical to
+ .B --domain=thekelleys.org.uk,192.168.0.0/24
+ .B --local=/thekelleys.org.uk/ --local=/0.168.192.in-addr.arpa/
++
++The address range can also be given as a network interface name, in which case
++all of the subnets currently assigned to the interface are used in matching the
++address. This allows hosts on different physical subnets to be given different
++domains in a way which updates automatically as the interface addresses change.
+ .TP
+ .B --dhcp-fqdn
+ In the default mode, dnsmasq inserts the unqualified names of
+diff --git a/src/dnsmasq.h b/src/dnsmasq.h
+index 51a1aa6..bfc0fd4 100644
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -975,6 +975,8 @@ struct dhcp_bridge {
+ struct cond_domain {
+   char *domain, *prefix; /* prefix is text-prefix on domain name */
++  char *interface;       /* These two set when domain comes from interface. */
++  struct addrlist *al;
+   struct in_addr start, end;
+   struct in6_addr start6, end6;
+   int is6, indexed, prefixlen;
+diff --git a/src/domain.c b/src/domain.c
+index 7166433..a893ce5 100644
+--- a/src/domain.c
++++ b/src/domain.c
+@@ -230,9 +230,17 @@ int is_rev_synth(int flag, union all_addr *addr, char *name)
+ static int match_domain(struct in_addr addr, struct cond_domain *c)
+ {
+-  if (!c->is6 &&
+-      ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
+-      ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
++  if (c->interface)
++    {
++      struct addrlist *al;
++      for (al = c->al; al; al = al->next)
++      if (!(al->flags & ADDRLIST_IPV6) &&
++          is_same_net_prefix(addr, al->addr.addr4, al->prefixlen))
++        return 1;
++    }
++  else if (!c->is6 &&
++         ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
++         ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
+     return 1;
+   return 0;
+@@ -259,12 +267,21 @@ char *get_domain(struct in_addr addr)
+ static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
+ {
+-  u64 addrpart = addr6part(addr);
+-  
+-  if (c->is6)
++    
++  /* subnet from interface address. */
++  if (c->interface)
++    {
++      struct addrlist *al;
++      for (al = c->al; al; al = al->next)
++      if (al->flags & ADDRLIST_IPV6 &&
++          is_same_net6(addr, &al->addr.addr6, al->prefixlen))
++        return 1;
++    }
++  else if (c->is6)
+     {
+       if (c->prefixlen >= 64)
+       {
++        u64 addrpart = addr6part(addr);
+         if (is_same_net6(addr, &c->start6, 64) &&
+             addrpart >= addr6part(&c->start6) &&
+             addrpart <= addr6part(&c->end6))
+@@ -273,7 +290,7 @@ static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
+       else if (is_same_net6(addr, &c->start6, c->prefixlen))
+       return 1;
+     }
+-
++    
+   return 0;
+ }
+diff --git a/src/network.c b/src/network.c
+index 4453b05..6166484 100644
+--- a/src/network.c
++++ b/src/network.c
+@@ -231,6 +231,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
+                        union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags) 
+ {
+   struct irec *iface;
++  struct cond_domain *cond;
+   int loopback;
+   struct ifreq ifr;
+   int tftp_ok = !!option_bool(OPT_TFTP);
+@@ -453,7 +454,37 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
+             }
+         }
+     }
+- 
++
++  /* Update addresses for domain=<domain>,<interface> */
++  for (cond = daemon->cond_domain; cond; cond = cond->next)
++    if (cond->interface && strncmp(label, cond->interface, IF_NAMESIZE) == 0)
++      {
++      struct addrlist *al;
++
++      if (param->spare)
++        {
++          al = param->spare;
++          param->spare = al->next;
++        }
++      else
++        al = whine_malloc(sizeof(struct addrlist));
++
++      if (addr->sa.sa_family == AF_INET)
++        {
++          al->addr.addr4 = addr->in.sin_addr;
++          al->flags = 0;
++        }
++      else
++        {
++          al->addr.addr6 =  addr->in6.sin6_addr;
++          al->flags = ADDRLIST_IPV6;
++        }
++
++      al->prefixlen = prefixlen;
++      al->next = cond->al;
++      cond->al = al;
++      }
++  
+   /* check whether the interface IP has been added already 
+      we call this routine multiple times. */
+   for (iface = daemon->interfaces; iface; iface = iface->next) 
+@@ -691,6 +722,7 @@ int enumerate_interfaces(int reset)
+   int errsave, ret = 1;
+   struct addrlist *addr, *tmp;
+   struct interface_name *intname;
++  struct cond_domain *cond;
+   struct irec *iface;
+ #ifdef HAVE_AUTH
+   struct auth_zone *zone;
+@@ -750,6 +782,19 @@ again:
+       intname->addr = NULL;
+     }
++  /* remove addresses stored against cond-domains. */
++  for (cond = daemon->cond_domain; cond; cond = cond->next)
++    {
++      for (addr = cond->al; addr; addr = tmp)
++      {
++        tmp = addr->next;
++        addr->next = spare;
++        spare = addr;
++      }
++      
++      cond->al = NULL;
++    }
++  
+   /* Remove list of addresses of local interfaces */
+   for (addr = daemon->interface_addrs; addr; addr = tmp)
+     {
+diff --git a/src/option.c b/src/option.c
+index c354ddf..39e1179 100644
+--- a/src/option.c
++++ b/src/option.c
+@@ -2492,9 +2492,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
+                         else if (!inet_pton(AF_INET6, arg, &new->end6))
+                           ret_err_free(gen_err, new);
+                       }
+-                    else 
++                    else if (option == 's')
++                      {
++                        /* subnet from interface. */
++                        new->interface = opt_string_alloc(comma);
++                        new->al = NULL;
++                      }
++                    else
+                       ret_err_free(gen_err, new);
+-
++                    
+                     if (option != 's' && prefstr)
+                       {
+                         if (!(new->prefix = canonicalise_opt(prefstr)) ||
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0006-Manpage-update-for-localise-queries.patch b/package/network/services/dnsmasq/patches/0006-Manpage-update-for-localise-queries.patch
new file mode 100644 (file)
index 0000000..1d4f127
--- /dev/null
@@ -0,0 +1,27 @@
+From 756a1dcc1925ed0f2768ededf0e20505ee15b9ff Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sat, 5 Mar 2022 18:13:15 +0000
+Subject: [PATCH 6/8] Manpage update for --localise-queries.
+
+Thanks to Leonardo Romor for the suggestion.
+---
+ man/dnsmasq.8 | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index f68a286..67c8055 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -304,7 +304,8 @@ Return answers to DNS queries from /etc/hosts and \fB--interface-name\fP and \fB
+ received. If a name has more than one address associated with
+ it, and at least one of those addresses is on the same subnet as the
+ interface to which the query was sent, then return only the
+-address(es) on that subnet. This allows for a server  to have multiple
++address(es) on that subnet and return all the available addresses otherwise.
++This allows for a server  to have multiple
+ addresses in /etc/hosts corresponding to each of its interfaces, and
+ hosts will get the correct address based on which network they are
+ attached to. Currently this facility is limited to IPv4.
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0007-Add-DNSMASQ_DATA_MISSING-envvar-to-lease-change-scri.patch b/package/network/services/dnsmasq/patches/0007-Add-DNSMASQ_DATA_MISSING-envvar-to-lease-change-scri.patch
new file mode 100644 (file)
index 0000000..ae16e79
--- /dev/null
@@ -0,0 +1,56 @@
+From 191924576ca105939c5275134ffcb8a2cb629bb2 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Tue, 22 Mar 2022 13:47:05 +0000
+Subject: [PATCH 7/8] Add DNSMASQ_DATA_MISSING envvar to lease-change script.
+
+---
+ man/dnsmasq.8 | 8 +++++++-
+ src/helper.c  | 6 ++++++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index 67c8055..fea89fa 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -1712,7 +1712,13 @@ If dnsmasq was compiled with HAVE_BROKEN_RTC, then
+ the length of the lease (in seconds) is stored in
+ DNSMASQ_LEASE_LENGTH, otherwise the time of lease expiry is stored in
+ DNSMASQ_LEASE_EXPIRES. The number of seconds until lease expiry is
+-always stored in DNSMASQ_TIME_REMAINING. 
++always stored in DNSMASQ_TIME_REMAINING.
++
++DNSMASQ_DATA_MISSING is set to "1" during "old" events for existing
++leases generated at startup to indicate that data not stored in the
++persistent lease database will not be present. This comprises everything
++other than IP address, hostname, MAC address, DUID, IAID and lease length
++or expiry time.
+ If a lease used to have a hostname, which is
+ removed, an "old" event is generated with the new state of the lease, 
+diff --git a/src/helper.c b/src/helper.c
+index 39e4b89..14330f3 100644
+--- a/src/helper.c
++++ b/src/helper.c
+@@ -421,6 +421,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
+             
+             end = extradata + data.ed_len;
+             buf = extradata;
++
++            lua_pushnumber(lua, data.ed_len == 0 ? 1 : 0);
++            lua_setfield(lua, -2, "data_missing");
+             
+             if (!is6)
+               buf = grab_extradata_lua(buf, end, "vendor_class");
+@@ -599,6 +602,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
+         
+         end = extradata + data.ed_len;
+         buf = extradata;
++
++        if (data.ed_len == 0)
++          my_setenv("DNSMASQ_DATA_MISSING", "1", &err);
+         
+         if (!is6)
+           buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS", &err);
+-- 
+2.35.1
+
diff --git a/package/network/services/dnsmasq/patches/0008-Fix-write-after-free-error-in-DHCPv6-code.-CVE-2022-.patch b/package/network/services/dnsmasq/patches/0008-Fix-write-after-free-error-in-DHCPv6-code.-CVE-2022-.patch
new file mode 100644 (file)
index 0000000..d18489c
--- /dev/null
@@ -0,0 +1,187 @@
+From 03345ecefeb0d82e3c3a4c28f27c3554f0611b39 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 31 Mar 2022 21:35:20 +0100
+Subject: [PATCH 8/8] Fix write-after-free error in DHCPv6 code. CVE-2022-0934
+ refers.
+
+---
+ CHANGELOG     |  3 +++
+ src/rfc3315.c | 48 +++++++++++++++++++++++++++---------------------
+ 2 files changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/CHANGELOG b/CHANGELOG
+index 87d6c2b..4bc7fb1 100644
+--- a/CHANGELOG
++++ b/CHANGELOG
+@@ -55,6 +55,9 @@ version 2.87
+       doesn't require hard-coding addresses. Thanks to Sten Spans for
+       the idea.
++      Fix write-after-free error in DHCPv6 server code.
++      CVE-2022-0934 refers.
++      
+       
+ version 2.86
+       Handle DHCPREBIND requests in the DHCPv6 server code.
+diff --git a/src/rfc3315.c b/src/rfc3315.c
+index cee8382..e218d26 100644
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -33,9 +33,9 @@ struct state {
+   unsigned int mac_len, mac_type;
+ };
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, 
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, 
+                            struct in6_addr *client_addr, int is_unicast, time_t now);
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
+ static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
+ static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
+ static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
+@@ -104,12 +104,12 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
+ }
+ /* This cost me blood to write, it will probably cost you blood to understand - srk. */
+-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz, 
++static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, 
+                            struct in6_addr *client_addr, int is_unicast, time_t now)
+ {
+   void *end = inbuff + sz;
+   void *opts = inbuff + 34;
+-  int msg_type = *((unsigned char *)inbuff);
++  int msg_type = *inbuff;
+   unsigned char *outmsgtypep;
+   void *opt;
+   struct dhcp_vendor *vendor;
+@@ -259,15 +259,15 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
+   return 1;
+ }
+-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
++static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
+ {
+   void *opt;
+-  int i, o, o1, start_opts;
++  int i, o, o1, start_opts, start_msg;
+   struct dhcp_opt *opt_cfg;
+   struct dhcp_netid *tagif;
+   struct dhcp_config *config = NULL;
+   struct dhcp_netid known_id, iface_id, v6_id;
+-  unsigned char *outmsgtypep;
++  unsigned char outmsgtype;
+   struct dhcp_vendor *vendor;
+   struct dhcp_context *context_tmp;
+   struct dhcp_mac *mac_opt;
+@@ -296,12 +296,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+   v6_id.next = state->tags;
+   state->tags = &v6_id;
+-  /* copy over transaction-id, and save pointer to message type */
+-  if (!(outmsgtypep = put_opt6(inbuff, 4)))
++  start_msg = save_counter(-1);
++  /* copy over transaction-id */
++  if (!put_opt6(inbuff, 4))
+     return 0;
+   start_opts = save_counter(-1);
+-  state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
+-   
++  state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
++    
+   /* We're going to be linking tags from all context we use. 
+      mark them as unused so we don't link one twice and break the list */
+   for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
+@@ -347,7 +348,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
+     
+     {  
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       o1 = new_opt6(OPTION6_STATUS_CODE);
+       put_opt6_short(DHCP6USEMULTI);
+       put_opt6_string("Use multicast");
+@@ -619,11 +620,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       struct dhcp_netid *solicit_tags;
+       struct dhcp_context *c;
+       
+-      *outmsgtypep = DHCP6ADVERTISE;
++      outmsgtype = DHCP6ADVERTISE;
+       
+       if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
+         {
+-          *outmsgtypep = DHCP6REPLY;
++          outmsgtype = DHCP6REPLY;
+           state->lease_allocate = 1;
+           o = new_opt6(OPTION6_RAPID_COMMIT);
+           end_opt6(o);
+@@ -809,7 +810,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       int start = save_counter(-1);
+       /* set reply message type */
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       state->lease_allocate = 1;
+       log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
+@@ -924,7 +925,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       int address_assigned = 0;
+       /* set reply message type */
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       
+       log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
+@@ -1057,7 +1058,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       int good_addr = 0;
+       /* set reply message type */
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       
+       log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
+       
+@@ -1121,7 +1122,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
+       if (ignore)
+         return 0;
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       tagif = add_options(state, 1);
+       break;
+       }
+@@ -1130,7 +1131,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+     case DHCP6RELEASE:
+       {
+       /* set reply message type */
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       log6_quiet(state, "DHCPRELEASE", NULL, NULL);
+@@ -1195,7 +1196,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+     case DHCP6DECLINE:
+       {
+       /* set reply message type */
+-      *outmsgtypep = DHCP6REPLY;
++      outmsgtype = DHCP6REPLY;
+       
+       log6_quiet(state, "DHCPDECLINE", NULL, NULL);
+@@ -1275,7 +1276,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+       }
+     }
+-  
++
++  /* Fill in the message type. Note that we store the offset,
++     not a direct pointer, since the packet memory may have been 
++     reallocated. */
++  ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
++
+   log_tags(tagif, state->xid);
+   log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
+   
+-- 
+2.35.1
+