As no package maintainer stepped up to fix this, I am NMUing the package with 
the enclosed changes.
diff -Nru connman-1.36/debian/changelog connman-1.36/debian/changelog
--- connman-1.36/debian/changelog       2021-10-09 22:49:52.000000000 +0200
+++ connman-1.36/debian/changelog       2022-02-26 06:06:06.000000000 +0100
@@ -1,3 +1,14 @@
+connman (1.36-2.4) unstable; urgency=medium
+
+  * d/patches: (Closes: #1004935)
+    + 0008-dnsproxy-Validate-input-data-before-using-them.patch: fixes
+      CVE-2022-23096, CVE-2022-23097
+    + 0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch: fixes
+      CVE-2022-23098
+  * Bump debhelper version from deprecated 11 to 12
+
+ -- Ross Vandegrift <rvandegr...@debian.org>  Fri, 25 Feb 2022 21:06:06 -0800
+
 connman (1.36-2.3) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru connman-1.36/debian/compat connman-1.36/debian/compat
--- connman-1.36/debian/compat  2021-10-09 22:49:52.000000000 +0200
+++ connman-1.36/debian/compat  1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-11
diff -Nru connman-1.36/debian/control connman-1.36/debian/control
--- connman-1.36/debian/control 2021-10-09 22:49:52.000000000 +0200
+++ connman-1.36/debian/control 2022-02-26 06:06:06.000000000 +0100
@@ -3,7 +3,7 @@
 Uploaders: Alf Gaida <aga...@siduction.org>
 Section: net
 Priority: optional
-Build-Depends: debhelper (>= 11~),
+Build-Depends: debhelper-compat (= 12),
                libudev-dev,
                libglib2.0-dev,
                libdbus-1-dev,
diff -Nru 
connman-1.36/debian/patches/0008-dnsproxy-Validate-input-data-before-using-them.patch
 
connman-1.36/debian/patches/0008-dnsproxy-Validate-input-data-before-using-them.patch
--- 
connman-1.36/debian/patches/0008-dnsproxy-Validate-input-data-before-using-them.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
connman-1.36/debian/patches/0008-dnsproxy-Validate-input-data-before-using-them.patch
       2022-02-26 06:06:06.000000000 +0100
@@ -0,0 +1,111 @@
+From: Daniel Wagner <w...@monom.org>
+Date: Tue, 25 Jan 2022 10:00:24 +0100
+Subject: dnsproxy: Validate input data before using them
+
+dnsproxy is not validating various input data. Add a bunch of checks.
+
+Fixes: CVE-2022-23097
+Fixes: CVE-2022-23096
+---
+ src/dnsproxy.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/src/dnsproxy.c b/src/dnsproxy.c
+index e297f1f..852fa44 100644
+--- a/src/dnsproxy.c
++++ b/src/dnsproxy.c
+@@ -1951,6 +1951,12 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+ 
+       if (offset < 0)
+               return offset;
++      if (reply_len < 0)
++              return -EINVAL;
++      if (reply_len < offset + 1)
++              return -EINVAL;
++      if ((size_t)reply_len < sizeof(struct domain_hdr))
++              return -EINVAL;
+ 
+       hdr = (void *)(reply + offset);
+       dns_id = reply[offset] | reply[offset + 1] << 8;
+@@ -1986,23 +1992,31 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+                */
+               if (req->append_domain && ntohs(hdr->qdcount) == 1) {
+                       uint16_t domain_len = 0;
+-                      uint16_t header_len;
++                      uint16_t header_len, payload_len;
+                       uint16_t dns_type, dns_class;
+                       uint8_t host_len, dns_type_pos;
+                       char uncompressed[NS_MAXDNAME], *uptr;
+                       char *ptr, *eom = (char *)reply + reply_len;
++                      char *domain;
+ 
+                       /*
+                        * ptr points to the first char of the hostname.
+                        * ->hostname.domain.net
+                        */
+                       header_len = offset + sizeof(struct domain_hdr);
++                      if (reply_len < header_len)
++                              return -EINVAL;
++                      payload_len = reply_len - header_len;
++
+                       ptr = (char *)reply + header_len;
+ 
+                       host_len = *ptr;
++                      domain = ptr + 1 + host_len;
++                      if (domain > eom)
++                              return -EINVAL;
++
+                       if (host_len > 0)
+-                              domain_len = strnlen(ptr + 1 + host_len,
+-                                              reply_len - header_len);
++                              domain_len = strnlen(domain, eom - domain);
+ 
+                       /*
+                        * If the query type is anything other than A or AAAA,
+@@ -2011,6 +2025,8 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+                        */
+                       dns_type_pos = host_len + 1 + domain_len + 1;
+ 
++                      if (ptr + (dns_type_pos + 3) > eom)
++                              return -EINVAL;
+                       dns_type = ptr[dns_type_pos] << 8 |
+                                                       ptr[dns_type_pos + 1];
+                       dns_class = ptr[dns_type_pos + 2] << 8 |
+@@ -2040,6 +2056,8 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+                               int new_len, fixed_len;
+                               char *answers;
+ 
++                              if (len > payload_len)
++                                      return -EINVAL;
+                               /*
+                                * First copy host (without domain name) into
+                                * tmp buffer.
+@@ -2054,6 +2072,8 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+                                * Copy type and class fields of the question.
+                                */
+                               ptr += len + domain_len + 1;
++                              if (ptr + NS_QFIXEDSZ > eom)
++                                      return -EINVAL;
+                               memcpy(uptr, ptr, NS_QFIXEDSZ);
+ 
+                               /*
+@@ -2063,6 +2083,8 @@ static int forward_dns_reply(unsigned char *reply, int 
reply_len, int protocol,
+                               uptr += NS_QFIXEDSZ;
+                               answers = uptr;
+                               fixed_len = answers - uncompressed;
++                              if (ptr + offset > eom)
++                                      return -EINVAL;
+ 
+                               /*
+                                * We then uncompress the result to buffer
+@@ -2256,9 +2278,7 @@ static gboolean udp_server_event(GIOChannel *channel, 
GIOCondition condition,
+       if (len < 12)
+               return TRUE;
+ 
+-      err = forward_dns_reply(buf, len, IPPROTO_UDP, data);
+-      if (err < 0)
+-              return TRUE;
++      forward_dns_reply(buf, len, IPPROTO_UDP, data);
+ 
+       return TRUE;
+ }
diff -Nru 
connman-1.36/debian/patches/0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch
 
connman-1.36/debian/patches/0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch
--- 
connman-1.36/debian/patches/0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
connman-1.36/debian/patches/0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch
      2022-02-26 06:06:06.000000000 +0100
@@ -0,0 +1,39 @@
+From: Matthias Gerstner <mgerst...@suse.de>
+Date: Tue, 25 Jan 2022 10:00:25 +0100
+Subject: dnsproxy: Avoid 100 % busy loop in TCP server case
+
+Once the TCP socket is connected and until the remote server is
+responding (if ever) ConnMan executes a 100 % CPU loop, since
+the connected socket will always be writable (G_IO_OUT).
+
+To fix this, modify the watch after the connection is established to
+remove the G_IO_OUT from the callback conditions.
+
+Fixes: CVE-2022-23098
+---
+ src/dnsproxy.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/dnsproxy.c b/src/dnsproxy.c
+index 852fa44..66b099a 100644
+--- a/src/dnsproxy.c
++++ b/src/dnsproxy.c
+@@ -2359,6 +2359,18 @@ hangup:
+                       }
+               }
+ 
++              /*
++               * Remove the G_IO_OUT flag from the watch, otherwise we end
++               * up in a busy loop, because the socket is constantly writable.
++               *
++               * There seems to be no better way in g_io to do that than
++               * re-adding the watch.
++               */
++              g_source_remove(server->watch);
++              server->watch = g_io_add_watch(server->channel,
++                      G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
++                      tcp_server_event, server);
++
+               server->connected = true;
+               server_list = g_slist_append(server_list, server);
+ 
diff -Nru connman-1.36/debian/patches/series connman-1.36/debian/patches/series
--- connman-1.36/debian/patches/series  2021-10-09 22:49:52.000000000 +0200
+++ connman-1.36/debian/patches/series  2022-02-26 06:06:06.000000000 +0100
@@ -5,3 +5,5 @@
 gdhcp-Avoid-leaking-stack-data-via-unitiialized-vari.patch
 dnsproxy-Add-length-checks-to-prevent-buffer-overflo.patch
 dnsproxy-Check-the-length-of-buffers-before-memcpy.patch
+0008-dnsproxy-Validate-input-data-before-using-them.patch
+0009-dnsproxy-Avoid-100-busy-loop-in-TCP-server-case.patch

Reply via email to