chiark / gitweb /
networkd: refactor link_add() ...
authorTom Gundersen <teg@jklm.no>
Tue, 18 Feb 2014 20:42:05 +0000 (21:42 +0100)
committerTom Gundersen <teg@jklm.no>
Tue, 18 Feb 2014 21:34:26 +0000 (22:34 +0100)
Don't set set **ret when returning r < 0, as matching on the errno may easily
give false positives in the future leading to null pointer dereference.

Reported-by: David Herrmann <dh.herrmann@gmail.com>
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd.h

index ec283d5..66bcb6b 100644 (file)
@@ -85,22 +85,33 @@ void link_free(Link *link) {
         free(link);
 }
 
+int link_get(Manager *m, int ifindex, Link **ret) {
+        Link *link;
+        uint64_t ifindex_64;
+
+        assert(m);
+        assert(m->links);
+        assert(ifindex);
+        assert(ret);
+
+        ifindex_64 = ifindex;
+        link = hashmap_get(m->links, &ifindex_64);
+        if (!link)
+                return -ENODEV;
+
+        *ret = link;
+
+        return 0;
+}
+
 int link_add(Manager *m, struct udev_device *device, Link **ret) {
         Link *link;
         Network *network;
         int r;
-        uint64_t ifindex;
 
         assert(m);
         assert(device);
 
-        ifindex = udev_device_get_ifindex(device);
-        link = hashmap_get(m->links, &ifindex);
-        if (link) {
-                *ret = link;
-                return -EEXIST;
-        }
-
         r = link_new(m, device, &link);
         if (r < 0)
                 return r;
@@ -926,7 +937,8 @@ static int link_enter_enslave(Link *link) {
         return 0;
 }
 
-static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
+                                void *userdata) {
         Link *link = userdata;
         int r;
 
@@ -953,7 +965,7 @@ static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         return 1;
 }
 
-static int link_get(Link *link) {
+static int link_getlink(Link *link) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
@@ -970,7 +982,8 @@ static int link_get(Link *link) {
                 return r;
         }
 
-        r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
+        r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
+                               link, 0, NULL);
         if (r < 0) {
                 log_error_link(link,
                                "Could not send rtnetlink message: %s", strerror(-r));
@@ -987,7 +1000,7 @@ int link_configure(Link *link) {
         assert(link->network);
         assert(link->state == _LINK_STATE_INVALID);
 
-        r = link_get(link);
+        r = link_getlink(link);
         if (r < 0) {
                 link_enter_failed(link);
                 return r;
index c1ad69b..f817d69 100644 (file)
@@ -145,30 +145,31 @@ bool manager_should_reload(Manager *m) {
 }
 
 static int manager_process_link(Manager *m, struct udev_device *device) {
-        Link *link;
+        Link *link = NULL;
         int r;
 
-        if (streq_ptr(udev_device_get_action(device), "remove")) {
-                uint64_t ifindex;
+        assert(m);
+        assert(device);
 
+        link_get(m, udev_device_get_ifindex(device), &link);
+
+        if (streq_ptr(udev_device_get_action(device), "remove")) {
                 log_debug("%s: link removed", udev_device_get_sysname(device));
 
-                ifindex = udev_device_get_ifindex(device);
-                link = hashmap_get(m->links, &ifindex);
-                if (!link)
+                if (link)
+                        link_free(link);
+        } else {
+                if (link) {
+                        log_debug("%s: link already exists, ignoring",
+                                  link->ifname);
                         return 0;
+                }
 
-                link_free(link);
-        } else {
                 r = link_add(m, device, &link);
                 if (r < 0) {
-                        if (r == -EEXIST)
-                                log_debug("%s: link already exists, ignoring",
-                                          link->ifname);
-                        else
-                                log_error("%s: could not handle link: %s",
-                                          udev_device_get_sysname(device),
-                                          strerror(-r));
+                        log_error("%s: could not handle link: %s",
+                                  udev_device_get_sysname(device),
+                                  strerror(-r));
                 } else
                         log_debug("%s: link (with ifindex %" PRIu64") added",
                                   link->ifname, link->ifindex);
@@ -264,9 +265,12 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
         Manager *m = userdata;
         Link *link;
         const char *name;
-        uint64_t ifindex_64;
         int r, ifindex;
 
+        assert(rtnl);
+        assert(message);
+        assert(m);
+
         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
         if (r < 0 || ifindex <= 0) {
                 log_debug("received RTM_NEWLINK message without valid ifindex");
@@ -288,9 +292,8 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
                 }
         }
 
-        ifindex_64 = ifindex;
-        link = hashmap_get(m->links, &ifindex_64);
-        if (!link) {
+        r = link_get(m, ifindex, &link);
+        if (r < 0) {
                 log_debug("received RTM_NEWLINK message for untracked ifindex %d", ifindex);
                 return 0;
         }
index 51d7757..5a1bf1a 100644 (file)
@@ -313,6 +313,7 @@ int config_parse_label(const char *unit, const char *filename, unsigned line,
 
 int link_new(Manager *manager, struct udev_device *device, Link **ret);
 void link_free(Link *link);
+int link_get(Manager *m, int ifindex, Link **ret);
 int link_add(Manager *manager, struct udev_device *device, Link **ret);
 int link_configure(Link *link);