networkd: take ref immediately after storing item in set
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 5 Jun 2020 12:24:57 +0000 (14:24 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 24 Jun 2020 08:38:15 +0000 (10:38 +0200)
I'm not sure if I understand the code correctly, but it seems that if
storig in the second set failed, we'd return with the first set having
no reference on the link object, and the link object could be freed in the
future, leaving the set with a dangling reference.

src/network/networkd-link.c
src/network/networkd-manager.c

index baa1cd3f7fd0e4ed9dac6d61b0c2eacab98edd0b..c2fb21c7360253fda4df24adbc3a7308fb308bd4 100644 (file)
@@ -3129,12 +3129,12 @@ static int link_configure_duid(Link *link) {
                 r = set_put(m->links_requesting_uuid, link);
                 if (r < 0)
                         return log_oom();
+                if (r > 0)
+                        link_ref(link);
 
                 r = set_put(m->duids_requesting_uuid, duid);
                 if (r < 0)
                         return log_oom();
-
-                link_ref(link);
         }
 
         return 0;
index 14a883aa30591079f397bbf43d3e37810e3a03cd..08666fd92d195495d38062e98a894afab3ed8177 100644 (file)
@@ -2312,12 +2312,12 @@ int manager_request_product_uuid(Manager *m, Link *link) {
                 r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
                 if (r < 0)
                         return log_oom();
+                if (r > 0)
+                        link_ref(link);
 
                 r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
                 if (r < 0)
                         return log_oom();
-
-                link_ref(link);
         }
 
         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {