[Pkg-utopia-maintainers] Bug#1090787: bookworm-pu: package avahi/0.8-10+deb12u1
Adrian Bunk
bunk at debian.org
Thu Dec 19 07:24:22 GMT 2024
Package: release.debian.org
Severity: normal
Tags: bookworm moreinfo
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: security at debian.org, Michael Biebl <biebl at debian.org>, Utopia Maintenance Team <pkg-utopia-maintainers at lists.alioth.debian.org>
* core: make sure there is rdata to process before parsing it.
Patch cherry-picked from upstream Git.
(CVE-2023-38472, Closes: #1054879)
* core: reject overly long TXT resource records.
Patches cherry-picked from upstream Git.
(CVE-2023-38469, Closes: #1054876)
* Ensure each label is at least one byte long.
Patch cherry-picked from upstream Git.
(CVE-2023-38470, Closes: #1054877)
* core: extract host name using avahi_unescape_label()
Patch cherry-picked from upstream Git.
(CVE-2023-38471, Closes: #1054878)
* common: derive alternative host name from its unescaped version.
Patch cherry-picked from upstream Git.
(CVE-2023-38473, Closes: #1054880)
* Fix browsing when invalid services present.
See https://github.com/lathiat/avahi/issues/212
Tagged moreinfo for two reasons:
1. This is work done by Michael Biebl, it would be fine for me
to close this request for a maintainer upload.
2. A question to the security team is whether the last item should
get a CVE, there is some discussion in the upstream issue about
that but apparently none has been assigned.
-------------- next part --------------
diffstat for avahi-0.8 avahi-0.8
changelog | 25 +
patches/Ensure-each-label-is-at-least-one-byte-long.patch | 54 +++
patches/common-derive-alternative-host-name-from-its-unescaped-ve.patch | 105 ++++++
patches/core-extract-host-name-using-avahi_unescape_label.patch | 70 ++++
patches/core-make-sure-there-is-rdata-to-process-before-parsing-i.patch | 42 ++
patches/core-no-longer-supply-bogus-services-to-callbacks.patch | 159 ++++++++++
patches/core-reject-overly-long-TXT-resource-records.patch | 45 ++
patches/series | 7
patches/tests-pass-overly-long-TXT-resource-records.patch | 60 +++
9 files changed, 567 insertions(+)
diff -Nru avahi-0.8/debian/changelog avahi-0.8/debian/changelog
--- avahi-0.8/debian/changelog 2023-04-19 14:51:49.000000000 +0300
+++ avahi-0.8/debian/changelog 2024-12-19 09:01:14.000000000 +0200
@@ -1,3 +1,28 @@
+avahi (0.8-10+deb12u1) bookworm; urgency=medium
+
+ * Non-maintainer upload.
+
+ [ Michael Biebl ]
+ * core: make sure there is rdata to process before parsing it.
+ Patch cherry-picked from upstream Git.
+ (CVE-2023-38472, Closes: #1054879)
+ * core: reject overly long TXT resource records.
+ Patches cherry-picked from upstream Git.
+ (CVE-2023-38469, Closes: #1054876)
+ * Ensure each label is at least one byte long.
+ Patch cherry-picked from upstream Git.
+ (CVE-2023-38470, Closes: #1054877)
+ * core: extract host name using avahi_unescape_label()
+ Patch cherry-picked from upstream Git.
+ (CVE-2023-38471, Closes: #1054878)
+ * common: derive alternative host name from its unescaped version.
+ Patch cherry-picked from upstream Git.
+ (CVE-2023-38473, Closes: #1054880)
+ * Fix browsing when invalid services present.
+ See https://github.com/lathiat/avahi/issues/212
+
+ -- Adrian Bunk <bunk at debian.org> Thu, 19 Dec 2024 09:01:14 +0200
+
avahi (0.8-10) unstable; urgency=medium
[ Felix Geyer ]
diff -Nru avahi-0.8/debian/patches/common-derive-alternative-host-name-from-its-unescaped-ve.patch avahi-0.8/debian/patches/common-derive-alternative-host-name-from-its-unescaped-ve.patch
--- avahi-0.8/debian/patches/common-derive-alternative-host-name-from-its-unescaped-ve.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/common-derive-alternative-host-name-from-its-unescaped-ve.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,105 @@
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Wed, 11 Oct 2023 17:45:44 +0200
+Subject: common: derive alternative host name from its unescaped version
+
+Normalization of input makes sure we don't have to deal with special
+cases like unescaped dot at the end of label.
+
+Fixes #451 #487
+CVE-2023-38473
+
+(cherry picked from commit b448c9f771bada14ae8de175695a9729f8646797)
+Origin: https://github.com/avahi/avahi/commit/b448c9f771bada14ae8de175695a9729f8646797
+---
+ avahi-common/alternative-test.c | 3 +++
+ avahi-common/alternative.c | 27 +++++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/avahi-common/alternative-test.c b/avahi-common/alternative-test.c
+index 9255435..681fc15 100644
+--- a/avahi-common/alternative-test.c
++++ b/avahi-common/alternative-test.c
+@@ -31,6 +31,9 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ const char* const test_strings[] = {
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX???????",
++ ").",
++ "\\.",
++ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\\",
+ "gurke",
+ "-",
+ " #",
+diff --git a/avahi-common/alternative.c b/avahi-common/alternative.c
+index b3d39f0..a094e6d 100644
+--- a/avahi-common/alternative.c
++++ b/avahi-common/alternative.c
+@@ -49,15 +49,20 @@ static void drop_incomplete_utf8(char *c) {
+ }
+
+ char *avahi_alternative_host_name(const char *s) {
++ char label[AVAHI_LABEL_MAX], alternative[AVAHI_LABEL_MAX*4+1];
++ char *alt, *r, *ret;
+ const char *e;
+- char *r;
++ size_t len;
+
+ assert(s);
+
+ if (!avahi_is_valid_host_name(s))
+ return NULL;
+
+- if ((e = strrchr(s, '-'))) {
++ if (!avahi_unescape_label(&s, label, sizeof(label)))
++ return NULL;
++
++ if ((e = strrchr(label, '-'))) {
+ const char *p;
+
+ e++;
+@@ -74,19 +79,18 @@ char *avahi_alternative_host_name(const char *s) {
+
+ if (e) {
+ char *c, *m;
+- size_t l;
+ int n;
+
+ n = atoi(e)+1;
+ if (!(m = avahi_strdup_printf("%i", n)))
+ return NULL;
+
+- l = e-s-1;
++ len = e-label-1;
+
+- if (l >= AVAHI_LABEL_MAX-1-strlen(m)-1)
+- l = AVAHI_LABEL_MAX-1-strlen(m)-1;
++ if (len >= AVAHI_LABEL_MAX-1-strlen(m)-1)
++ len = AVAHI_LABEL_MAX-1-strlen(m)-1;
+
+- if (!(c = avahi_strndup(s, l))) {
++ if (!(c = avahi_strndup(label, len))) {
+ avahi_free(m);
+ return NULL;
+ }
+@@ -100,7 +104,7 @@ char *avahi_alternative_host_name(const char *s) {
+ } else {
+ char *c;
+
+- if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-2)))
++ if (!(c = avahi_strndup(label, AVAHI_LABEL_MAX-1-2)))
+ return NULL;
+
+ drop_incomplete_utf8(c);
+@@ -109,6 +113,13 @@ char *avahi_alternative_host_name(const char *s) {
+ avahi_free(c);
+ }
+
++ alt = alternative;
++ len = sizeof(alternative);
++ ret = avahi_escape_label(r, strlen(r), &alt, &len);
++
++ avahi_free(r);
++ r = avahi_strdup(ret);
++
+ assert(avahi_is_valid_host_name(r));
+
+ return r;
diff -Nru avahi-0.8/debian/patches/core-extract-host-name-using-avahi_unescape_label.patch avahi-0.8/debian/patches/core-extract-host-name-using-avahi_unescape_label.patch
--- avahi-0.8/debian/patches/core-extract-host-name-using-avahi_unescape_label.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/core-extract-host-name-using-avahi_unescape_label.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,70 @@
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Mon, 23 Oct 2023 13:38:35 +0200
+Subject: core: extract host name using avahi_unescape_label()
+
+Previously we could create invalid escape sequence when we split the
+string on dot. For example, from valid host name "foo\\.bar" we have
+created invalid name "foo\\" and tried to set that as the host name
+which crashed the daemon.
+
+Fixes #453
+
+CVE-2023-38471
+
+(cherry picked from commit 894f085f402e023a98cbb6f5a3d117bd88d93b09)
+Origin: https://github.com/avahi/avahi/commit/894f085f402e023a98cbb6f5a3d117bd88d93b09
+---
+ avahi-core/server.c | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/avahi-core/server.c b/avahi-core/server.c
+index e507750..40f1d68 100644
+--- a/avahi-core/server.c
++++ b/avahi-core/server.c
+@@ -1295,7 +1295,11 @@ static void update_fqdn(AvahiServer *s) {
+ }
+
+ int avahi_server_set_host_name(AvahiServer *s, const char *host_name) {
+- char *hn = NULL;
++ char label_escaped[AVAHI_LABEL_MAX*4+1];
++ char label[AVAHI_LABEL_MAX];
++ char *hn = NULL, *h;
++ size_t len;
++
+ assert(s);
+
+ AVAHI_CHECK_VALIDITY(s, !host_name || avahi_is_valid_host_name(host_name), AVAHI_ERR_INVALID_HOST_NAME);
+@@ -1305,17 +1309,28 @@ int avahi_server_set_host_name(AvahiServer *s, const char *host_name) {
+ else
+ hn = avahi_normalize_name_strdup(host_name);
+
+- hn[strcspn(hn, ".")] = 0;
++ h = hn;
++ if (!avahi_unescape_label((const char **)&hn, label, sizeof(label))) {
++ avahi_free(h);
++ return AVAHI_ERR_INVALID_HOST_NAME;
++ }
++
++ avahi_free(h);
++
++ h = label_escaped;
++ len = sizeof(label_escaped);
++ if (!avahi_escape_label(label, strlen(label), &h, &len))
++ return AVAHI_ERR_INVALID_HOST_NAME;
+
+- if (avahi_domain_equal(s->host_name, hn) && s->state != AVAHI_SERVER_COLLISION) {
+- avahi_free(hn);
++ if (avahi_domain_equal(s->host_name, label_escaped) && s->state != AVAHI_SERVER_COLLISION)
+ return avahi_server_set_errno(s, AVAHI_ERR_NO_CHANGE);
+- }
+
+ withdraw_host_rrs(s);
+
+ avahi_free(s->host_name);
+- s->host_name = hn;
++ s->host_name = avahi_strdup(label_escaped);
++ if (!s->host_name)
++ return AVAHI_ERR_NO_MEMORY;
+
+ update_fqdn(s);
+
diff -Nru avahi-0.8/debian/patches/core-make-sure-there-is-rdata-to-process-before-parsing-i.patch avahi-0.8/debian/patches/core-make-sure-there-is-rdata-to-process-before-parsing-i.patch
--- avahi-0.8/debian/patches/core-make-sure-there-is-rdata-to-process-before-parsing-i.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/core-make-sure-there-is-rdata-to-process-before-parsing-i.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,42 @@
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Thu, 19 Oct 2023 17:36:44 +0200
+Subject: core: make sure there is rdata to process before parsing it
+
+Fixes #452
+
+CVE-2023-38472
+
+(cherry picked from commit b024ae5749f4aeba03478e6391687c3c9c8dee40)
+Origin: https://github.com/avahi/avahi/commit/b024ae5749f4aeba03478e6391687c3c9c8dee40
+---
+ avahi-client/client-test.c | 3 +++
+ avahi-daemon/dbus-entry-group.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c
+index 7d04a6a..57750a4 100644
+--- a/avahi-client/client-test.c
++++ b/avahi-client/client-test.c
+@@ -258,6 +258,9 @@ int main (AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ printf("%s\n", avahi_strerror(avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "Lathiat's Site", "_http._tcp", NULL, NULL, 80, "foo=bar", NULL)));
+ printf("add_record: %d\n", avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "\5booya", 6));
+
++ error = avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "", 0);
++ assert(error != AVAHI_OK);
++
+ avahi_entry_group_commit (group);
+
+ domain = avahi_domain_browser_new (avahi, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, 0, avahi_domain_browser_callback, (char*) "omghai3u");
+diff --git a/avahi-daemon/dbus-entry-group.c b/avahi-daemon/dbus-entry-group.c
+index 4e879a5..aa23d4b 100644
+--- a/avahi-daemon/dbus-entry-group.c
++++ b/avahi-daemon/dbus-entry-group.c
+@@ -340,7 +340,7 @@ DBusHandlerResult avahi_dbus_msg_entry_group_impl(DBusConnection *c, DBusMessage
+ if (!(r = avahi_record_new_full (name, clazz, type, ttl)))
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_NO_MEMORY, NULL);
+
+- if (avahi_rdata_parse (r, rdata, size) < 0) {
++ if (!rdata || avahi_rdata_parse (r, rdata, size) < 0) {
+ avahi_record_unref (r);
+ return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_RDATA, NULL);
+ }
diff -Nru avahi-0.8/debian/patches/core-no-longer-supply-bogus-services-to-callbacks.patch avahi-0.8/debian/patches/core-no-longer-supply-bogus-services-to-callbacks.patch
--- avahi-0.8/debian/patches/core-no-longer-supply-bogus-services-to-callbacks.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/core-no-longer-supply-bogus-services-to-callbacks.patch 2024-12-19 09:01:14.000000000 +0200
@@ -0,0 +1,159 @@
+From: Evgeny Vereshchagin <evvers at ya.ru>
+Date: Sun, 12 Nov 2023 01:16:58 +0000
+Subject: core: no longer supply bogus services to callbacks
+
+It was technically a DOS allowing packets with service names like
+"bogus.service.local" to bring down `avahi-browse -a`. In practice
+it was usually triggered by misconfigured smart devices but it isn't
+that hard to forge packets like that and send them deliberately.
+
+The tests are added to make sure invalid service names are rejected and
+valid service names keep working. The fuzz target is updated to make
+sure that avahi_service_name_split always supplies valid arguments to
+avahi_service_name_join. avahi now logs what exactly it fails to split
+```
+avahi-daemon[176]: Failed to split service name '0.1.9.1.8.8.e.f.f.f.f.a.a.1.4.7.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa'
+avahi-daemon[176]: Failed to split service name 'bogus\032.\032\209\129\208\181\209\128\208\178\208\184\209\129.local'
+avahi-daemon[176]: Failed to split service name '255.20.254.169.in-addr.arpa'
+avahi-daemon[176]: Failed to split service name 'bogus\032.\032\209\129\208\181\209\128\208\178\208\184\209\129.local'
+avahi-daemon[176]: Failed to split service name '33.93.168.192.in-addr.arpa'
+```
+when --debug is passed to it (which makes that part consistent with the
+other places where weird packets are rejected).
+
+Closes https://github.com/lathiat/avahi/issues/212
+
+(cherry picked from commit 93b14365c1c1e04efd1a890e8caa01a2a514bfd8)
+Origin: https://github.com/avahi/avahi/commit/93b14365c1c1e04efd1a890e8caa01a2a514bfd8
+---
+ avahi-common/domain-test.c | 36 ++++++++++++++++++++++++++++++++++++
+ avahi-common/domain.c | 14 ++++++++++++++
+ avahi-core/browse-service-type.c | 2 +-
+ avahi-core/browse-service.c | 2 +-
+ 4 files changed, 52 insertions(+), 2 deletions(-)
+
+diff --git a/avahi-common/domain-test.c b/avahi-common/domain-test.c
+index 3acc1c1..22ca430 100644
+--- a/avahi-common/domain-test.c
++++ b/avahi-common/domain-test.c
+@@ -26,6 +26,7 @@
+ #include <assert.h>
+
+ #include "domain.h"
++#include "error.h"
+ #include "malloc.h"
+
+ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+@@ -34,6 +35,7 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ const char *p;
+ size_t size;
+ char name[64], type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
++ int res;
+
+ printf("%s\n", s = avahi_normalize_name_strdup("foo.foo\\046."));
+ avahi_free(s);
+@@ -133,5 +135,39 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ assert(!avahi_is_valid_fqdn("::1"));
+ assert(!avahi_is_valid_fqdn(".192.168.50.1."));
+
++ res = avahi_service_name_split("test._ssh._tcp.local", name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
++ assert(res >= 0);
++ assert(strcmp(name, "test") == 0);
++ assert(strcmp(type, "_ssh._tcp") == 0);
++ assert(strcmp(domain, "local") == 0);
++
++ res = avahi_service_name_split("test._hop._sub._ssh._tcp.local", name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
++ assert(res >= 0);
++ assert(strcmp(name, "test") == 0);
++ assert(strcmp(type, "_hop._sub._ssh._tcp") == 0);
++ assert(strcmp(domain, "local") == 0);
++
++ res = avahi_service_name_split("_qotd._udp.hey.local", NULL, 0, type, sizeof(type), domain, sizeof(domain));
++ assert(res >= 0);
++ assert(strcmp(type, "_qotd._udp") == 0);
++ assert(strcmp(domain, "hey.local") == 0);
++
++ res = avahi_service_name_split("_wat._sub._qotd._udp.hey.local", NULL, 0, type, sizeof(type), domain, sizeof(domain));
++ assert(res >= 0);
++ assert(strcmp(type, "_wat._sub._qotd._udp") == 0);
++ assert(strcmp(domain, "hey.local") == 0);
++
++ res = avahi_service_name_split("wat.bogus.service.local", name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
++ assert(res == AVAHI_ERR_INVALID_SERVICE_TYPE);
++
++ res = avahi_service_name_split("bogus.service.local", NULL, 0, type, sizeof(type), domain, sizeof(domain));
++ assert(res == AVAHI_ERR_INVALID_SERVICE_TYPE);
++
++ res = avahi_service_name_split("", name, sizeof(name), type, sizeof(type), domain, sizeof(domain));
++ assert(res == AVAHI_ERR_INVALID_SERVICE_NAME);
++
++ res = avahi_service_name_split("", NULL, 0, type, sizeof(type), domain, sizeof(domain));
++ assert(res == AVAHI_ERR_INVALID_SERVICE_TYPE);
++
+ return 0;
+ }
+diff --git a/avahi-common/domain.c b/avahi-common/domain.c
+index e66d241..795b4fd 100644
+--- a/avahi-common/domain.c
++++ b/avahi-common/domain.c
+@@ -500,6 +500,7 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
+ DOMAIN
+ } state;
+ int type_empty = 1, domain_empty = 1;
++ char *oname, *otype, *odomain;
+
+ assert(p);
+ assert(type);
+@@ -507,6 +508,10 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
+ assert(domain);
+ assert(domain_size > 0);
+
++ oname = name;
++ otype = type;
++ odomain = domain;
++
+ if (name) {
+ assert(name_size > 0);
+ *name = 0;
+@@ -569,6 +574,15 @@ int avahi_service_name_split(const char *p, char *name, size_t name_size, char *
+ }
+ }
+
++ if ((oname && !avahi_is_valid_service_name(oname)))
++ return AVAHI_ERR_INVALID_SERVICE_NAME;
++
++ if (!avahi_is_valid_service_type_generic(otype))
++ return AVAHI_ERR_INVALID_SERVICE_TYPE;
++
++ if (!avahi_is_valid_domain_name(odomain))
++ return AVAHI_ERR_INVALID_DOMAIN_NAME;
++
+ return 0;
+ }
+
+diff --git a/avahi-core/browse-service-type.c b/avahi-core/browse-service-type.c
+index b1fc7af..f0d6938 100644
+--- a/avahi-core/browse-service-type.c
++++ b/avahi-core/browse-service-type.c
+@@ -65,7 +65,7 @@ static void record_browser_callback(
+ assert(record->key->type == AVAHI_DNS_TYPE_PTR);
+
+ if (avahi_service_name_split(record->data.ptr.name, NULL, 0, type, sizeof(type), domain, sizeof(domain)) < 0) {
+- avahi_log_warn("Invalid service type '%s'", record->key->name);
++ avahi_log_debug("Failed to split service name '%s'", record->data.ptr.name);
+ return;
+ }
+
+diff --git a/avahi-core/browse-service.c b/avahi-core/browse-service.c
+index 63e0275..e924bae 100644
+--- a/avahi-core/browse-service.c
++++ b/avahi-core/browse-service.c
+@@ -69,7 +69,7 @@ static void record_browser_callback(
+ flags |= AVAHI_LOOKUP_RESULT_LOCAL;
+
+ if (avahi_service_name_split(record->data.ptr.name, service, sizeof(service), type, sizeof(type), domain, sizeof(domain)) < 0) {
+- avahi_log_warn("Failed to split '%s'", record->key->name);
++ avahi_log_debug("Failed to split service name '%s'", record->data.ptr.name);
+ return;
+ }
+
diff -Nru avahi-0.8/debian/patches/core-reject-overly-long-TXT-resource-records.patch avahi-0.8/debian/patches/core-reject-overly-long-TXT-resource-records.patch
--- avahi-0.8/debian/patches/core-reject-overly-long-TXT-resource-records.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/core-reject-overly-long-TXT-resource-records.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,45 @@
+From: Evgeny Vereshchagin <evvers at ya.ru>
+Date: Mon, 23 Oct 2023 20:29:31 +0000
+Subject: core: reject overly long TXT resource records
+
+Closes https://github.com/lathiat/avahi/issues/455
+
+CVE-2023-38469
+
+(cherry picked from commit a337a1ba7d15853fb56deef1f464529af6e3a1cf)
+Origin: https://github.com/avahi/avahi/commit/a337a1ba7d15853fb56deef1f464529af6e3a1cf
+---
+ avahi-core/rr.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/avahi-core/rr.c b/avahi-core/rr.c
+index 7fa0bee..b03a24c 100644
+--- a/avahi-core/rr.c
++++ b/avahi-core/rr.c
+@@ -32,6 +32,7 @@
+ #include <avahi-common/malloc.h>
+ #include <avahi-common/defs.h>
+
++#include "dns.h"
+ #include "rr.h"
+ #include "log.h"
+ #include "util.h"
+@@ -688,11 +689,17 @@ int avahi_record_is_valid(AvahiRecord *r) {
+ case AVAHI_DNS_TYPE_TXT: {
+
+ AvahiStringList *strlst;
++ size_t used = 0;
+
+- for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next)
++ for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next) {
+ if (strlst->size > 255 || strlst->size <= 0)
+ return 0;
+
++ used += 1+strlst->size;
++ if (used > AVAHI_DNS_RDATA_MAX)
++ return 0;
++ }
++
+ return 1;
+ }
+ }
diff -Nru avahi-0.8/debian/patches/Ensure-each-label-is-at-least-one-byte-long.patch avahi-0.8/debian/patches/Ensure-each-label-is-at-least-one-byte-long.patch
--- avahi-0.8/debian/patches/Ensure-each-label-is-at-least-one-byte-long.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/Ensure-each-label-is-at-least-one-byte-long.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,54 @@
+From: =?utf-8?b?UGV0ciBNZW7FocOtaw==?= <pemensik at redhat.com>
+Date: Tue, 11 Apr 2023 15:29:59 +0200
+Subject: Ensure each label is at least one byte long
+
+The only allowed exception is single dot, where it should return empty
+string.
+
+Fixes #454.
+
+(cherry picked from commit 94cb6489114636940ac683515417990b55b5d66c)
+Origin: https://github.com/avahi/avahi/commit/94cb6489114636940ac683515417990b55b5d66c
+---
+ avahi-common/domain-test.c | 14 ++++++++++++++
+ avahi-common/domain.c | 2 +-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/avahi-common/domain-test.c b/avahi-common/domain-test.c
+index cf763ec..3acc1c1 100644
+--- a/avahi-common/domain-test.c
++++ b/avahi-common/domain-test.c
+@@ -45,6 +45,20 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ printf("%s\n", s = avahi_normalize_name_strdup("fo\\\\o\\..f oo."));
+ avahi_free(s);
+
++ printf("%s\n", s = avahi_normalize_name_strdup("."));
++ avahi_free(s);
++
++ s = avahi_normalize_name_strdup(",.=.}.=.?-.}.=.?.?.}.}.?.?.?.z.?.?.}.}."
++ "}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.=.=.?.?.}.}.?.?.}.}.}"
++ ".?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.=.=.?.?.}.}.?.?.?.zM.?`"
++ "?.}.}.}.?.?.?.r.=.?.}.=.?.?.}.?.?.?.}.=.?.?.}??.}.}.?.?."
++ "?.z.?.?.}.}.}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.?`?.}.}.}."
++ "??.?.zM.?`?.}.}.}.?.?.?.r.=.?.}.=.?.?.}.?.?.?.}.=.?.?.}?"
++ "?.}.}.?.?.?.z.?.?.}.}.}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM."
++ "?`?.}.}.}.?.?.?.r.=.=.?.?`.?.?}.}.}.?.?.?.r.=.?.}.=.?.?."
++ "}.?.?.?.}.=.?.?.}");
++ assert(s == NULL);
++
+ printf("%i\n", avahi_domain_equal("\\065aa bbb\\.\\046cc.cc\\\\.dee.fff.", "Aaa BBB\\.\\.cc.cc\\\\.dee.fff"));
+ printf("%i\n", avahi_domain_equal("A", "a"));
+
+diff --git a/avahi-common/domain.c b/avahi-common/domain.c
+index 3b1ab68..e66d241 100644
+--- a/avahi-common/domain.c
++++ b/avahi-common/domain.c
+@@ -201,7 +201,7 @@ char *avahi_normalize_name(const char *s, char *ret_s, size_t size) {
+ }
+
+ if (!empty) {
+- if (size < 1)
++ if (size < 2)
+ return NULL;
+
+ *(r++) = '.';
diff -Nru avahi-0.8/debian/patches/series avahi-0.8/debian/patches/series
--- avahi-0.8/debian/patches/series 2023-04-19 14:51:49.000000000 +0300
+++ avahi-0.8/debian/patches/series 2024-12-19 09:01:00.000000000 +0200
@@ -14,3 +14,10 @@
Avoid-infinite-loop-in-avahi-daemon-by-handling-HUP-event.patch
dbus-Use-non-deprecated-installation-path.patch
Emit-error-if-requested-service-is-not-found.patch
+core-make-sure-there-is-rdata-to-process-before-parsing-i.patch
+core-reject-overly-long-TXT-resource-records.patch
+tests-pass-overly-long-TXT-resource-records.patch
+Ensure-each-label-is-at-least-one-byte-long.patch
+core-extract-host-name-using-avahi_unescape_label.patch
+common-derive-alternative-host-name-from-its-unescaped-ve.patch
+core-no-longer-supply-bogus-services-to-callbacks.patch
diff -Nru avahi-0.8/debian/patches/tests-pass-overly-long-TXT-resource-records.patch avahi-0.8/debian/patches/tests-pass-overly-long-TXT-resource-records.patch
--- avahi-0.8/debian/patches/tests-pass-overly-long-TXT-resource-records.patch 1970-01-01 02:00:00.000000000 +0200
+++ avahi-0.8/debian/patches/tests-pass-overly-long-TXT-resource-records.patch 2024-12-19 08:52:04.000000000 +0200
@@ -0,0 +1,60 @@
+From: Evgeny Vereshchagin <evvers at ya.ru>
+Date: Wed, 25 Oct 2023 18:15:42 +0000
+Subject: tests: pass overly long TXT resource records
+
+to make sure they don't crash avahi any more.
+
+It reproduces https://github.com/lathiat/avahi/issues/455
+
+(cherry picked from commit c6cab87df290448a63323c8ca759baa516166237)
+Origin: https://github.com/avahi/avahi/commit/c6cab87df290448a63323c8ca759baa516166237
+---
+ avahi-client/client-test.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c
+index 57750a4..2f51e3e 100644
+--- a/avahi-client/client-test.c
++++ b/avahi-client/client-test.c
+@@ -22,6 +22,7 @@
+ #endif
+
+ #include <stdio.h>
++#include <string.h>
+ #include <assert.h>
+
+ #include <avahi-client/client.h>
+@@ -33,6 +34,8 @@
+ #include <avahi-common/malloc.h>
+ #include <avahi-common/timeval.h>
+
++#include <avahi-core/dns.h>
++
+ static const AvahiPoll *poll_api = NULL;
+ static AvahiSimplePoll *simple_poll = NULL;
+
+@@ -222,6 +225,9 @@ int main (AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ uint32_t cookie;
+ struct timeval tv;
+ AvahiAddress a;
++ uint8_t rdata[AVAHI_DNS_RDATA_MAX+1];
++ AvahiStringList *txt = NULL;
++ int r;
+
+ simple_poll = avahi_simple_poll_new();
+ poll_api = avahi_simple_poll_get(simple_poll);
+@@ -261,6 +267,14 @@ int main (AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
+ error = avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "", 0);
+ assert(error != AVAHI_OK);
+
++ memset(rdata, 1, sizeof(rdata));
++ r = avahi_string_list_parse(rdata, sizeof(rdata), &txt);
++ assert(r >= 0);
++ assert(avahi_string_list_serialize(txt, NULL, 0) == sizeof(rdata));
++ error = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", "_qotd._tcp", NULL, NULL, 123, txt);
++ assert(error == AVAHI_ERR_INVALID_RECORD);
++ avahi_string_list_free(txt);
++
+ avahi_entry_group_commit (group);
+
+ domain = avahi_domain_browser_new (avahi, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, 0, avahi_domain_browser_callback, (char*) "omghai3u");
More information about the Pkg-utopia-maintainers
mailing list