From 46f6fb1bd16c4f1dded06d33f160c194ec9d6ae0 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 1 Jun 2021 19:30:19 -0500 Subject: [PATCH] netconfig: Cancel pending address set command It is possible that the address set command succeeds just after a netconfig object has been destroyed. ==6485== Invalid read of size 8 ==6485== at 0x458A6D: netconfig_ipv4_routes_install (netconfig.c:629) ==6485== by 0x458D1C: netconfig_ipv4_ifaddr_add_cmd_cb (netconfig.c:689) ==6485== by 0x4A5E7B: process_message (netlink.c:181) ==6485== by 0x4A626A: can_read_data (netlink.c:289) ==6485== by 0x4A3E19: io_callback (io.c:120) ==6485== by 0x4A27B5: l_main_iterate (main.c:478) ==6485== by 0x4A28F6: l_main_run (main.c:525) ==6485== by 0x4A2C0E: l_main_run_with_signal (main.c:647) ==6485== by 0x404D27: main (main.c:542) ==6485== Address 0x4a47290 is 32 bytes inside a block of size 104 free'd ==6485== at 0x48399CB: free (vg_replace_malloc.c:538) ==6485== by 0x49998B: l_free (util.c:136) ==6485== by 0x457699: netconfig_free (netconfig.c:130) ==6485== by 0x45A038: netconfig_destroy (netconfig.c:1163) ==6485== by 0x41FD16: station_free (station.c:3613) ==6485== by 0x42020E: station_destroy_interface (station.c:3710) ==6485== by 0x4B990E: interface_instance_free (dbus-service.c:510) ==6485== by 0x4BC193: _dbus_object_tree_remove_interface (dbus-service.c:1694) ==6485== by 0x4BA22A: _dbus_object_tree_object_destroy (dbus-service.c:795) ==6485== by 0x4B078D: l_dbus_unregister_object (dbus.c:1537) ==6485== by 0x417ACB: device_netdev_notify (device.c:361) ==6485== by 0x4062B6: netdev_free (netdev.c:808) ==6485== Block was alloc'd at ==6485== at 0x483879F: malloc (vg_replace_malloc.c:307) ==6485== by 0x499857: l_malloc (util.c:62) ==6485== by 0x459DC0: netconfig_new (netconfig.c:1115) ==6485== by 0x41FC29: station_create (station.c:3592) ==6485== by 0x4207B3: station_netdev_watch (station.c:3864) ==6485== by 0x411A17: netdev_initial_up_cb (netdev.c:5588) ==6485== by 0x4A5E7B: process_message (netlink.c:181) ==6485== by 0x4A626A: can_read_data (netlink.c:289) ==6485== by 0x4A3E19: io_callback (io.c:120) ==6485== by 0x4A27B5: l_main_iterate (main.c:478) ==6485== by 0x4A28F6: l_main_run (main.c:525) ==6485== by 0x4A2C0E: l_main_run_with_signal (main.c:647) ==6485== --- src/netconfig.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/netconfig.c b/src/netconfig.c index f0f45cb1..d739cc57 100644 --- a/src/netconfig.c +++ b/src/netconfig.c @@ -68,6 +68,8 @@ struct netconfig { struct l_acd *acd; + uint32_t addr4_add_cmd_id; + uint32_t addr6_add_cmd_id; uint32_t route4_add_gateway_cmd_id; }; @@ -680,6 +682,8 @@ static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type, { struct netconfig *netconfig = user_data; + netconfig->addr4_add_cmd_id = 0; + if (error && error != -EEXIST) { l_error("netconfig: Failed to add IP address. " "Error %d: %s", error, strerror(-error)); @@ -702,6 +706,8 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type, struct netconfig *netconfig = user_data; struct l_rtnl_route *gateway; + netconfig->addr6_add_cmd_id = 0; + if (error && error != -EEXIST) { l_error("netconfig: Failed to add IPv6 address. " "Error %d: %s", error, strerror(-error)); @@ -765,10 +771,11 @@ static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client, return; } - L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, + L_WARN_ON(!(netconfig->addr4_add_cmd_id = + l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, netconfig->v4_address, netconfig_ipv4_ifaddr_add_cmd_cb, - netconfig, NULL)); + netconfig, NULL))); break; case L_DHCP_CLIENT_EVENT_LEASE_RENEWED: break; @@ -859,10 +866,11 @@ static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data) switch (event) { case L_ACD_EVENT_AVAILABLE: - L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, + L_WARN_ON(!(netconfig->addr4_add_cmd_id = + l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, netconfig->v4_address, netconfig_ipv4_ifaddr_add_cmd_cb, - netconfig, NULL)); + netconfig, NULL))); return; case L_ACD_EVENT_CONFLICT: /* @@ -907,10 +915,11 @@ static void netconfig_ipv4_select_and_install(struct netconfig *netconfig) l_acd_destroy(netconfig->acd); netconfig->acd = NULL; - L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, + L_WARN_ON(!(netconfig->addr4_add_cmd_id = + l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, netconfig->v4_address, netconfig_ipv4_ifaddr_add_cmd_cb, - netconfig, NULL)); + netconfig, NULL))); } return; @@ -945,9 +954,10 @@ static void netconfig_ipv6_select_and_install(struct netconfig *netconfig) address = netconfig_get_static6_address(netconfig); if (address) { netconfig->rtm_v6_protocol = RTPROT_STATIC; - L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, address, + L_WARN_ON(!(netconfig->addr6_add_cmd_id = + l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, address, netconfig_ipv6_ifaddr_add_cmd_cb, - netconfig, NULL)); + netconfig, NULL))); l_rtnl_address_free(address); return; } @@ -1064,6 +1074,16 @@ bool netconfig_reset(struct netconfig *netconfig) netconfig->route4_add_gateway_cmd_id = 0; } + if (netconfig->addr4_add_cmd_id) { + l_netlink_cancel(rtnl, netconfig->addr4_add_cmd_id); + netconfig->addr4_add_cmd_id = 0; + } + + if (netconfig->addr6_add_cmd_id) { + l_netlink_cancel(rtnl, netconfig->addr6_add_cmd_id); + netconfig->addr6_add_cmd_id = 0; + } + if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol) resolve_revert(netconfig->resolve);