]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: when adding names to packet fails, remove them from label compression hash...
authorLennart Poettering <lennart@poettering.net>
Thu, 12 Sep 2024 15:05:24 +0000 (17:05 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 23 Oct 2024 08:22:28 +0000 (10:22 +0200)
let's make sure we undo any pollution of the label compression hash
table.

Fixes: #33671
src/resolve/resolved-dns-packet.c

index bfd4d48f52317be5a06d42aeed2d3a0fd8070c7f..2684944b75ef2417285aa7b5d0b69828b7567473 100644 (file)
@@ -557,7 +557,8 @@ int dns_packet_append_name(
                 bool canonical_candidate,
                 size_t *start) {
 
-        size_t saved_size;
+        _cleanup_free_ char **added_entries = NULL; /* doesn't own the strings! this is just regular pointer array, not a NULL-terminated strv! */
+        size_t n_added_entries = 0, saved_size;
         int r;
 
         assert(p);
@@ -598,6 +599,11 @@ int dns_packet_append_name(
                 if (allow_compression) {
                         _cleanup_free_ char *s = NULL;
 
+                        if (!GREEDY_REALLOC(added_entries, n_added_entries + 1)) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
                         s = strdup(z);
                         if (!s) {
                                 r = -ENOMEM;
@@ -608,7 +614,8 @@ int dns_packet_append_name(
                         if (r < 0)
                                 goto fail;
 
-                        TAKE_PTR(s);
+                        /* Keep track of the entries we just added (note that the string is owned by the hashtable, not this array!) */
+                        added_entries[n_added_entries++] = TAKE_PTR(s);
                 }
         }
 
@@ -623,6 +630,12 @@ done:
         return 0;
 
 fail:
+        /* Remove all label compression names we added again */
+        FOREACH_ARRAY(s, added_entries, n_added_entries) {
+                hashmap_remove(p->names, *s);
+                free(*s);
+        }
+
         dns_packet_truncate(p, saved_size);
         return r;
 }