summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch')
-rw-r--r--meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch278
1 files changed, 278 insertions, 0 deletions
diff --git a/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch b/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch
new file mode 100644
index 0000000000..a186bb4095
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/network-fix-Link-reference-counter-issue.patch
@@ -0,0 +1,278 @@
+From cc2d7efc5ca09a7de4bec55e80476986839a655c Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Fri, 14 May 2021 15:58:15 +0900
+Subject: [PATCH] network: fix Link reference counter issue
+
+Previously, when link_new() fails, `link_unref()` was called, so,
+`Manager::links` may become dirty.
+This introduces `link_drop_or_unref()` and it will be called on
+failure.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd-stable/commit/cc2d7efc5ca09a7de4bec55e80476986839a655c]
+Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
+
+---
+ src/network/networkd-link.c | 240 ++++++++++++++++++------------------
+ 1 file changed, 122 insertions(+), 118 deletions(-)
+
+diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
+index b56c232eca..d493afda4c 100644
+--- a/src/network/networkd-link.c
++++ b/src/network/networkd-link.c
+@@ -540,109 +540,6 @@ static int link_update_flags(Link *link,
+ return 0;
+ }
+
+-static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
+- _cleanup_(link_unrefp) Link *link = NULL;
+- uint16_t type;
+- const char *ifname, *kind = NULL;
+- int r, ifindex;
+- unsigned short iftype;
+-
+- assert(manager);
+- assert(message);
+- assert(ret);
+-
+- /* check for link kind */
+- r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
+- if (r == 0) {
+- (void) sd_netlink_message_read_string(message, IFLA_INFO_KIND, &kind);
+- r = sd_netlink_message_exit_container(message);
+- if (r < 0)
+- return r;
+- }
+-
+- r = sd_netlink_message_get_type(message, &type);
+- if (r < 0)
+- return r;
+- else if (type != RTM_NEWLINK)
+- return -EINVAL;
+-
+- r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
+- if (r < 0)
+- return r;
+- else if (ifindex <= 0)
+- return -EINVAL;
+-
+- r = sd_rtnl_message_link_get_type(message, &iftype);
+- if (r < 0)
+- return r;
+-
+- r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
+- if (r < 0)
+- return r;
+-
+- link = new(Link, 1);
+- if (!link)
+- return -ENOMEM;
+-
+- *link = (Link) {
+- .n_ref = 1,
+- .manager = manager,
+- .state = LINK_STATE_PENDING,
+- .ifindex = ifindex,
+- .iftype = iftype,
+-
+- .n_dns = (unsigned) -1,
+- .dns_default_route = -1,
+- .llmnr = _RESOLVE_SUPPORT_INVALID,
+- .mdns = _RESOLVE_SUPPORT_INVALID,
+- .dnssec_mode = _DNSSEC_MODE_INVALID,
+- .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
+- };
+-
+- link->ifname = strdup(ifname);
+- if (!link->ifname)
+- return -ENOMEM;
+-
+- if (kind) {
+- link->kind = strdup(kind);
+- if (!link->kind)
+- return -ENOMEM;
+- }
+-
+- r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t *)&link->master_ifindex);
+- if (r < 0)
+- log_link_debug_errno(link, r, "New device has no master, continuing without");
+-
+- r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
+- if (r < 0)
+- log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
+-
+- if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
+- return -ENOMEM;
+-
+- r = hashmap_ensure_allocated(&manager->links, NULL);
+- if (r < 0)
+- return r;
+-
+- r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
+- if (r < 0)
+- return r;
+-
+- r = link_update_flags(link, message, false);
+- if (r < 0)
+- return r;
+-
+- *ret = TAKE_PTR(link);
+-
+- return 0;
+-}
+-
+ void link_ntp_settings_clear(Link *link) {
+ link->ntp = strv_free(link->ntp);
+ }
+@@ -2030,9 +1927,9 @@ static void link_drop_requests(Link *lin
+ request_drop(req);
+ }
+
+-void link_drop(Link *link) {
++Link *link_drop(Link *link) {
+ if (!link)
+- return;
++ return NULL;
+
+ assert(link->manager);
+
+@@ -2057,7 +1954,7 @@ void link_drop(Link *link) {
+
+ /* The following must be called at last. */
+ assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
+- link_unref(link);
++ return link_unref(link);
+ }
+
+ static int link_joined(Link *link) {
+@@ -3295,6 +3192,112 @@ ipv4ll_address_fail:
+
+ return 0;
+ }
++
++static Link *link_drop_or_unref(Link *link) {
++ if (!link)
++ return NULL;
++ if (!link->manager)
++ return link_unref(link);
++ return link_drop(link);
++}
++
++DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref);
++
++static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
++ _cleanup_(link_drop_or_unrefp) Link *link = NULL;
++ uint16_t type;
++ _cleanup_free_ char *ifname = NULL, *kind = NULL;
++ int r, ifindex;
++ unsigned short iftype;
++
++ assert(manager);
++ assert(message);
++ assert(ret);
++
++ r = sd_netlink_message_get_type(message, &type);
++ if (r < 0)
++ return r;
++ else if (type != RTM_NEWLINK)
++ return -EINVAL;
++
++ r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
++ if (r < 0)
++ return r;
++ else if (ifindex <= 0)
++ return -EINVAL;
++
++ r = sd_rtnl_message_link_get_type(message, &iftype);
++ if (r < 0)
++ return r;
++
++ r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, &ifname);
++ if (r < 0)
++ return r;
++
++ /* check for link kind */
++ r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
++ if (r >= 0) {
++ (void) sd_netlink_message_read_string_strdup(message, IFLA_INFO_KIND, &kind);
++ r = sd_netlink_message_exit_container(message);
++ if (r < 0)
++ return r;
++ }
++
++ link = new(Link, 1);
++ if (!link)
++ return -ENOMEM;
++
++ *link = (Link) {
++ .n_ref = 1,
++ .state = LINK_STATE_PENDING,
++ .ifindex = ifindex,
++ .iftype = iftype,
++ .ifname = TAKE_PTR(ifname),
++ .kind = TAKE_PTR(kind),
++
++ .n_dns = (unsigned) -1,
++ .dns_default_route = -1,
++ .llmnr = _RESOLVE_SUPPORT_INVALID,
++ .mdns = _RESOLVE_SUPPORT_INVALID,
++ .dnssec_mode = _DNSSEC_MODE_INVALID,
++ .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
++ };
++
++ r = hashmap_ensure_allocated(&manager->links, NULL);
++ if (r < 0)
++ return r;
++
++ r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
++ if (r < 0)
++ return r;
++
++ link->manager = manager;
++
++ r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t*) &link->master_ifindex);
++ if (r < 0)
++ log_link_debug_errno(link, r, "New device has no master, continuing without");
++
++ r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
++ if (r < 0)
++ log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
++
++ if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
++ return -ENOMEM;
++
++ r = link_update_flags(link, message, false);
++ if (r < 0)
++ return r;
++
++ *ret = TAKE_PTR(link);
++
++ return 0;
++}
+
+ int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
+ _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+
+--- a/src/network/networkd-link.h 2021-09-02 18:04:16.900542857 +0530
++++ b/src/network/networkd-link.h 2021-09-02 18:18:56.776571563 +0530
+@@ -175,7 +175,7 @@ DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_d
+
+ int link_get(Manager *m, int ifindex, Link **ret);
+ int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
+-void link_drop(Link *link);
++Link *link_drop(Link *link);
+
+ int link_down(Link *link, link_netlink_message_handler_t callback);
+
+