blob: c2c3a5dd3d6bebff81f3335397907e676acbdb94 [file] [log] [blame] [edit]
From 78eab31128479f06e30beb8c1cbf99dd921e2524 Mon Sep 17 00:00:00 2001
From: Hugo Muis <198191869+friendlyhugo@users.noreply.github.com>
Date: Sun, 2 Mar 2025 18:06:24 +0100
Subject: [PATCH] core: fix uncontrolled recursion bug using a simple loop
detection algorithm
Closes https://github.com/avahi/avahi/issues/501
CVE: CVE-2026-24401
Upstream: https://github.com/avahi/avahi/commit/78eab31128479f06e30beb8c1cbf99dd921e2524
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
avahi-core/browse.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/avahi-core/browse.c b/avahi-core/browse.c
index ad08bd65f..e00cbed84 100644
--- a/avahi-core/browse.c
+++ b/avahi-core/browse.c
@@ -401,6 +401,40 @@ static int lookup_go(AvahiSRBLookup *l) {
return n;
}
+static int lookup_exists_in_path(AvahiSRBLookup* lookup, AvahiSRBLookup* from, AvahiSRBLookup* to) {
+ AvahiRList* rl;
+ if (from == to)
+ return 0;
+ for (rl = from->cname_lookups; rl; rl = rl->rlist_next) {
+ int r = lookup_exists_in_path(lookup, rl->data, to);
+ if (r == 1) {
+ /* loop detected, propagate result */
+ return r;
+ } else if (r == 0) {
+ /* is loop detected? */
+ return lookup == from;
+ } else {
+ /* `to` not found, continue */
+ continue;
+ }
+ }
+ /* no path found */
+ return -1;
+}
+
+static int cname_would_create_loop(AvahiSRBLookup* l, AvahiSRBLookup* n) {
+ int ret;
+ if (l == n)
+ /* Loop to self */
+ return 1;
+
+ ret = lookup_exists_in_path(n, l->record_browser->root_lookup, l);
+
+ /* Path to n always exists */
+ assert(ret != -1);
+ return ret;
+}
+
static void lookup_handle_cname(AvahiSRBLookup *l, AvahiIfIndex interface, AvahiProtocol protocol, AvahiLookupFlags flags, AvahiRecord *r) {
AvahiKey *k;
AvahiSRBLookup *n;
@@ -420,6 +454,12 @@ static void lookup_handle_cname(AvahiSRBLookup *l, AvahiIfIndex interface, Avahi
return;
}
+ if (cname_would_create_loop(l, n)) {
+ /* CNAME loops are not allowed */
+ lookup_unref(n);
+ return;
+ }
+
l->cname_lookups = avahi_rlist_prepend(l->cname_lookups, lookup_ref(n));
lookup_go(n);