diff options
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.patch | 278 |
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); + + |