From d26267ddf1bd8b0ba0ea05f703b407cbde7b5701 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 4 Jun 2019 14:25:09 +0900 Subject: [PATCH 1/3] network: fix double free on error path --- src/network/networkd-routing-policy-rule.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index f6253215ed8..637f8d5966f 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -275,8 +275,8 @@ static int routing_policy_rule_add_internal(Manager *m, rule->tos = tos; rule->fwmark = fwmark; rule->table = table; - rule->iif = iif; - rule->oif = oif; + rule->iif = TAKE_PTR(iif); + rule->oif = TAKE_PTR(oif); rule->protocol = protocol; rule->sport = *sport; rule->dport = *dport; @@ -292,9 +292,7 @@ static int routing_policy_rule_add_internal(Manager *m, if (ret) *ret = rule; - rule = NULL; - iif = oif = NULL; - + TAKE_PTR(rule); return 0; } From 9f08a578a80a5fc759b9ce7299ab7fdd2e60c814 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 4 Jun 2019 14:40:21 +0900 Subject: [PATCH 2/3] network: remove unused argument in routing_policy_rule_configure() --- src/network/networkd-link.c | 2 +- src/network/networkd-routing-policy-rule.c | 2 +- src/network/networkd-routing-policy-rule.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 6613992a091..74c0b103d47 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -829,7 +829,7 @@ static int link_request_set_routing_policy_rule(Link *link) { continue; } - r = routing_policy_rule_configure(rule, link, NULL, false); + r = routing_policy_rule_configure(rule, link, NULL); if (r < 0) { log_link_warning_errno(link, r, "Could not set routing policy rules: %m"); link_enter_failed(link); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 637f8d5966f..a1e56ec4367 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -472,7 +472,7 @@ static int routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, return 1; } -int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netlink_message_handler_t callback, bool update) { +int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netlink_message_handler_t callback) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h index 4ee0b5489ef..0b3204ad9c2 100644 --- a/src/network/networkd-routing-policy-rule.h +++ b/src/network/networkd-routing-policy-rule.h @@ -57,7 +57,7 @@ void routing_policy_rule_free(RoutingPolicyRule *rule); DEFINE_NETWORK_SECTION_FUNCTIONS(RoutingPolicyRule, routing_policy_rule_free); -int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback, bool update); +int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback); int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback); int routing_policy_rule_add(Manager *m, int family, const union in_addr_union *from, uint8_t from_prefixlen, const union in_addr_union *to, uint8_t to_prefixlen, From 9ee92e7ed8aa9494d963e09099cf3f80f65d3314 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 6 Jun 2019 00:42:05 +0900 Subject: [PATCH 3/3] network: check stored object is euivalent to what we want to remove When object A is stored in Manager::rules and B is in ::rules_foreign, and compare function for the object cannot distinguish them, then freeing A causes B to be removed from rules_foreign or vice versa. Hopefully fixes #12731. --- src/network/networkd-routing-policy-rule.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index a1e56ec4367..faa9f8576c7 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -46,8 +46,10 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) { } if (rule->manager) { - set_remove(rule->manager->rules, rule); - set_remove(rule->manager->rules_foreign, rule); + if (set_get(rule->manager->rules, rule) == rule) + set_remove(rule->manager->rules, rule); + if (set_get(rule->manager->rules_foreign, rule) == rule) + set_remove(rule->manager->rules_foreign, rule); } network_config_section_free(rule->section);