From 88cbbc48d5efff9726694557ca6c3f698f3affe4 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 11 Oct 2023 17:45:44 +0200
Subject: [PATCH] avahi: 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

Upstream-Status: Backport [https://github.com/lathiat/avahi/commit/b448c9f771bada14ae8de175695a9729f8646797]
CVE: CVE-2023-38473

Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
---
 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;
--
2.40.0
