From 1c9a736ed55feaf9760afa36a71901e230c45094 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 28 Apr 2021 10:38:23 -0500 Subject: [PATCH] netconfig: Cancel outstanding rtnl commands It is possible for the RTNL command callback to come after netconfig_reset or netconfig_destroy has been called. Make sure that any outstanding commands that might access the netconfig object are canceled. src/netconfig.c:netconfig_ipv4_dhcp_event_handler() DHCPv4 event 0 src/netconfig.c:netconfig_ifaddr_added() wlan0: ifaddr 192.168.1.55/24 broadcast 192.168.1.255 ^CTerminate src/netdev.c:netdev_free() Freeing netdev wlan0[15] src/device.c:device_free() src/station.c:station_free() src/netconfig.c:netconfig_destroy() src/netconfig.c:netconfig_reset() src/netconfig.c:netconfig_reset_v4() 16 src/netconfig.c:netconfig_reset_v4() Stopping client Removing scan context for wdev c src/scan.c:scan_context_free() sc: 0x4a3cc10 ==12792== Invalid read of size 8 ==12792== at 0x43BF5A: netconfig_route_add_cmd_cb (netconfig.c:600) ==12792== by 0x4727FA: process_message (netlink.c:181) ==12792== by 0x4727FA: can_read_data (netlink.c:289) ==12792== by 0x470F4B: io_callback (io.c:120) ==12792== by 0x47016C: l_main_iterate (main.c:478) ==12792== by 0x47023B: l_main_run (main.c:525) ==12792== by 0x47023B: l_main_run (main.c:507) ==12792== by 0x47044B: l_main_run_with_signal (main.c:647) ==12792== by 0x403EDB: main (main.c:490) --- src/netconfig.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/netconfig.c b/src/netconfig.c index a4ff35df..ddd7b8a3 100644 --- a/src/netconfig.c +++ b/src/netconfig.c @@ -67,6 +67,8 @@ struct netconfig { struct resolve *resolve; struct l_acd *acd; + + uint32_t route4_add_gateway_cmd_id; }; static struct l_netlink *rtnl; @@ -585,12 +587,25 @@ static void netconfig_ifaddr_ipv6_cmd_cb(int error, uint16_t type, netconfig_ifaddr_ipv6_notify(type, data, len, user_data); } +static void netconfig_route_generic_cb(int error, uint16_t type, + const void *data, uint32_t len, + void *user_data) +{ + if (error) { + l_error("netconfig: Failed to add route. Error %d: %s", + error, strerror(-error)); + return; + } +} + static void netconfig_route_add_cmd_cb(int error, uint16_t type, const void *data, uint32_t len, void *user_data) { struct netconfig *netconfig = user_data; + netconfig->route4_add_gateway_cmd_id = 0; + if (error) { l_error("netconfig: Failed to add route. Error %d: %s", error, strerror(-error)); @@ -627,7 +642,7 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig) if (!l_rtnl_route4_add_connected(rtnl, netconfig->ifindex, prefix_len, network, ip, netconfig->rtm_protocol, - netconfig_route_add_cmd_cb, + netconfig_route_generic_cb, netconfig, NULL)) { l_error("netconfig: Failed to add subnet route."); @@ -643,11 +658,13 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig) return false; } - if (!l_rtnl_route4_add_gateway(rtnl, netconfig->ifindex, gateway, ip, + netconfig->route4_add_gateway_cmd_id = + l_rtnl_route4_add_gateway(rtnl, netconfig->ifindex, gateway, ip, ROUTE_PRIORITY_OFFSET, netconfig->rtm_protocol, netconfig_route_add_cmd_cb, - netconfig, NULL)) { + netconfig, NULL); + if (!netconfig->route4_add_gateway_cmd_id) { l_error("netconfig: Failed to add route for: %s gateway.", gateway); @@ -695,7 +712,7 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type, if (gateway) { L_WARN_ON(!l_rtnl_route_add(rtnl, netconfig->ifindex, gateway, - netconfig_route_add_cmd_cb, + netconfig_route_generic_cb, netconfig, NULL)); l_rtnl_route_free(gateway); } @@ -1034,6 +1051,11 @@ bool netconfig_reset(struct netconfig *netconfig) { struct netdev *netdev = netdev_find(netconfig->ifindex); + if (netconfig->route4_add_gateway_cmd_id) { + l_netlink_cancel(rtnl, netconfig->route4_add_gateway_cmd_id); + netconfig->route4_add_gateway_cmd_id = 0; + } + if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol) resolve_revert(netconfig->resolve);