File: core-fix-uncontrolled-recursion-bug-using-a-simple-loop-d.patch

package info (click to toggle)
avahi 0.8-18
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,884 kB
  • sloc: ansic: 41,028; sh: 6,097; xml: 4,594; cs: 2,185; makefile: 1,742; python: 441; cpp: 224; sed: 16
file content (70 lines) | stat: -rw-r--r-- 2,129 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
From: Hugo Muis <198191869+friendlyhugo@users.noreply.github.com>
Date: Sun, 2 Mar 2025 18:06:24 +0100
Subject: core: fix uncontrolled recursion bug using a simple loop detection
 algorithm

Closes https://github.com/avahi/avahi/issues/501

(cherry picked from commit 78eab31128479f06e30beb8c1cbf99dd921e2524)
---
 avahi-core/browse.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/avahi-core/browse.c b/avahi-core/browse.c
index 57435fc..d7d541b 100644
--- a/avahi-core/browse.c
+++ b/avahi-core/browse.c
@@ -400,6 +400,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;
@@ -419,6 +453,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);