3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 13:02:44 +01:00

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)
This commit is contained in:
Denis Kenzior 2021-04-28 10:38:23 -05:00
parent e5550ed58f
commit 1c9a736ed5

View File

@ -67,6 +67,8 @@ struct netconfig {
struct resolve *resolve; struct resolve *resolve;
struct l_acd *acd; struct l_acd *acd;
uint32_t route4_add_gateway_cmd_id;
}; };
static struct l_netlink *rtnl; 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); 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, static void netconfig_route_add_cmd_cb(int error, uint16_t type,
const void *data, uint32_t len, const void *data, uint32_t len,
void *user_data) void *user_data)
{ {
struct netconfig *netconfig = user_data; struct netconfig *netconfig = user_data;
netconfig->route4_add_gateway_cmd_id = 0;
if (error) { if (error) {
l_error("netconfig: Failed to add route. Error %d: %s", l_error("netconfig: Failed to add route. Error %d: %s",
error, strerror(-error)); 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, if (!l_rtnl_route4_add_connected(rtnl, netconfig->ifindex,
prefix_len, network, ip, prefix_len, network, ip,
netconfig->rtm_protocol, netconfig->rtm_protocol,
netconfig_route_add_cmd_cb, netconfig_route_generic_cb,
netconfig, NULL)) { netconfig, NULL)) {
l_error("netconfig: Failed to add subnet route."); l_error("netconfig: Failed to add subnet route.");
@ -643,11 +658,13 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
return false; 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, ROUTE_PRIORITY_OFFSET,
netconfig->rtm_protocol, netconfig->rtm_protocol,
netconfig_route_add_cmd_cb, 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.", l_error("netconfig: Failed to add route for: %s gateway.",
gateway); gateway);
@ -695,7 +712,7 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
if (gateway) { if (gateway) {
L_WARN_ON(!l_rtnl_route_add(rtnl, netconfig->ifindex, L_WARN_ON(!l_rtnl_route_add(rtnl, netconfig->ifindex,
gateway, gateway,
netconfig_route_add_cmd_cb, netconfig_route_generic_cb,
netconfig, NULL)); netconfig, NULL));
l_rtnl_route_free(gateway); l_rtnl_route_free(gateway);
} }
@ -1034,6 +1051,11 @@ bool netconfig_reset(struct netconfig *netconfig)
{ {
struct netdev *netdev = netdev_find(netconfig->ifindex); 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) if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol)
resolve_revert(netconfig->resolve); resolve_revert(netconfig->resolve);