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
1 changed files with 26 additions and 4 deletions

View File

@ -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);