$NetBSD: patch-CVE-2023-38473,v 1.1 2025/02/26 11:43:05 nia Exp $

[PATCH] 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

https://github.com/avahi/avahi/commit/b448c9f771bada14ae8de175695a9729f8646797.patch

--- avahi-common/alternative.c.orig	2015-04-01 04:58:14.145727222 +0000
+++ 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 
 
     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 
     } 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 
         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;
