Skip to content

Commit

Permalink
ipacm: fix the heap-use-after-free issue on bootup Fix race condition…
Browse files Browse the repository at this point in the history
… between nat delete rule and update timestamp
  • Loading branch information
coderstory authored and Verevka committed Sep 17, 2017
1 parent 8db6abb commit 46f6547
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 129 deletions.
4 changes: 1 addition & 3 deletions data-ipa-cfg-mgr/ipacm/src/Android.mk
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
BOARD_PLATFORM_LIST := msm8916
BOARD_PLATFORM_LIST += msm8909
BOARD_IPAv3_LIST := msm8998
BOARD_IPAv3_LIST += sdm845
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
Expand Down Expand Up @@ -32,7 +30,7 @@ ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DDEBUG
endif

ifeq ($(call is-board-platform-in-list,$(BOARD_IPAv3_LIST)),true)
ifeq ($(TARGET_BOARD_PLATFORM),msmcobalt)
LOCAL_CFLAGS += -DFEATURE_IPA_V3
endif

Expand Down
8 changes: 8 additions & 0 deletions data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ int IPACM_Config::Init(void)
goto fail;
}

/* Check wlan AP-AP access mode configuration */
if (cfg->num_wlan_guest_ap == 2)
{
IPACMDBG_H("IPACM_Config::Both wlan APs can not be configured in guest ap mode. \n");
IPACMDBG_H("IPACM_Config::configure both APs in full access mode or at least one in guest ap mode. \n");
ret = IPACM_FAILURE;
goto fail;
}
/* Construct IPACM Iface table */
ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries;
if (iface_table != NULL)
Expand Down
35 changes: 13 additions & 22 deletions data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt,
case IPA_HANDLE_WAN_UP:
IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
CreateConnTrackThreads();
TriggerWANUp(data);
if(!isWanUp())
{
TriggerWANUp(data);
}
break;

case IPA_HANDLE_WAN_DOWN:
Expand Down Expand Up @@ -210,8 +213,8 @@ int IPACM_ConntrackListener::CheckNatIface(
sizeof(pNatIfaces[i].iface_name)) == 0)
{
IPACMDBG_H("Nat iface (%s), entry (%d), dont cache",
pNatIfaces[i].iface_name, i);
iptodot("with ipv4 address: ", nat_iface_ipv4_addr[i]);
pNatIfaces[i].iface_name, j);
iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]);
*NatIface = true;
return IPACM_SUCCESS;
}
Expand Down Expand Up @@ -353,14 +356,6 @@ void IPACM_ConntrackListener::TriggerWANUp(void *in_param)
return;
}

if(isWanUp())
{
if (wan_ipaddr != wanup_data->ipv4_addr)
TriggerWANDown(wan_ipaddr);
else
return;
}

WanUp = true;
isStaMode = wanup_data->is_sta;
IPACMDBG("isStaMode: %d\n", isStaMode);
Expand Down Expand Up @@ -460,20 +455,16 @@ int IPACM_ConntrackListener::CreateNatThreads(void)

void IPACM_ConntrackListener::TriggerWANDown(uint32_t wan_addr)
{
int ret = 0;
IPACMDBG_H("Deleting ipv4 nat table with");
IPACMDBG_H(" public ip address(0x%x): %d.%d.%d.%d\n", wan_addr,
((wan_addr>>24) & 0xFF), ((wan_addr>>16) & 0xFF),
((wan_addr>>8) & 0xFF), (wan_addr & 0xFF));
IPACMDBG_H("Deleting ipv4 nat table with");
IPACMDBG_H(" public ip address(0x%x): %d.%d.%d.%d\n", wan_addr,
((wan_addr>>24) & 0xFF), ((wan_addr>>16) & 0xFF),
((wan_addr>>8) & 0xFF), (wan_addr & 0xFF));

WanUp = false;

if(nat_inst != NULL)
{
ret = nat_inst->DeleteTable(wan_addr);
if (ret)
return;

WanUp = false;
wan_ipaddr = 0;
nat_inst->DeleteTable(wan_addr);
}
}

Expand Down
62 changes: 12 additions & 50 deletions data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -74,17 +74,6 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
return;
}

num_wan_ul_fl_rule_v4 = 0;
num_wan_ul_fl_rule_v6 = 0;
is_active = true;
modem_ul_v4_set = false;
modem_ul_v6_set = false;
is_mode_switch = false;
if_ipv4_subnet =0;
each_client_rt_rule_count[IPA_IP_v4] = 0;
each_client_rt_rule_count[IPA_IP_v6] = 0;
eth_client_len = 0;

/* support eth multiple clients */
if(iface_query != NULL)
{
Expand Down Expand Up @@ -115,14 +104,22 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
}
}

num_wan_ul_fl_rule_v4 = 0;
num_wan_ul_fl_rule_v6 = 0;

memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));

is_active = true;
memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));

is_mode_switch = false;
if_ipv4_subnet =0;
memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
modem_ul_v4_set = false;
modem_ul_v6_set = false;
memset(ipv6_prefix, 0, sizeof(ipv6_prefix));

/* ODU routing table initilization */
Expand Down Expand Up @@ -160,6 +157,8 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
}
}

each_client_rt_rule_count[IPA_IP_v4] = 0;
each_client_rt_rule_count[IPA_IP_v6] = 0;
if(iface_query != NULL && tx_prop != NULL)
{
for(i=0; i<iface_query->num_tx_props; i++)
Expand Down Expand Up @@ -877,12 +876,6 @@ int IPACM_Lan::handle_wan_down(bool is_sta_mode)
close(fd);
return IPACM_FAILURE;
}
if (num_wan_ul_fl_rule_v4 == 0)
{
IPACMERR("No modem UL rules were installed, return...\n");
close(fd);
return IPACM_FAILURE;
}
if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4,
IPA_IP_v4, num_wan_ul_fl_rule_v4) == false)
{
Expand Down Expand Up @@ -1802,8 +1795,6 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
uint32_t tx_index;
int eth_index,v6_num;
const int NUM = 1;
char cmd[200] = {0};
uint32_t ipv4_addr;

if(tx_prop == NULL)
{
Expand Down Expand Up @@ -1881,17 +1872,6 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n",
eth_index,
get_client_memptr(eth_client, eth_index)->hdr_hdl_v4);

/* add static arp entry */
ipv4_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
snprintf(cmd, sizeof(cmd), "ip neighbor change %d.%d.%d.%d lladdr %02x:%02x:%02x:%02x:%02x:%02x dev %s nud permanent",
(unsigned char)(ipv4_addr >> 24), (unsigned char)(ipv4_addr >> 16),
(unsigned char)(ipv4_addr >> 8), (unsigned char)ipv4_addr,
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5],
dev_name);
IPACMDBG_H("%s\n", cmd);
system(cmd);

strlcpy(rt_rule->rt_tbl_name,
IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name,
sizeof(rt_rule->rt_tbl_name));
Expand All @@ -1905,7 +1885,7 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
rt_rule_entry->rule.hashable = true;
#endif
if (false == m_routing.AddRoutingRule(rt_rule))
{
Expand Down Expand Up @@ -2346,8 +2326,6 @@ int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
uint32_t tx_index;
int num_eth_client_tmp = num_eth_client;
int num_v6;
char cmd[200] = {0};
uint32_t ipv4_addr;

IPACMDBG_H("total client: %d\n", num_eth_client_tmp);

Expand Down Expand Up @@ -2406,13 +2384,6 @@ int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false;
get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0;

ipv4_addr = get_client_memptr(eth_client, clt_indx)->v4_addr;
snprintf(cmd, sizeof(cmd), "ip neighbor del %d.%d.%d.%d dev %s",
(unsigned char)(ipv4_addr >> 24), (unsigned char)(ipv4_addr >> 16),
(unsigned char)(ipv4_addr >> 8), (unsigned char)ipv4_addr, dev_name);
system(cmd);
IPACMDBG_H("%s\n", cmd);

for (; clt_indx < num_eth_client_tmp - 1; clt_indx++)
{
memcpy(get_client_memptr(eth_client, clt_indx)->mac,
Expand Down Expand Up @@ -2478,8 +2449,6 @@ int IPACM_Lan::handle_down_evt()
{
int i;
int res = IPACM_SUCCESS;
char cmd[200] = {0};
uint32_t ipv4_addr;

IPACMDBG_H("lan handle_down_evt\n ");
if (ipa_if_cate == ODU_IF)
Expand Down Expand Up @@ -2670,13 +2639,6 @@ int IPACM_Lan::handle_down_evt()
IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
for (i = 0; i < num_eth_client; i++)
{
ipv4_addr = get_client_memptr(eth_client, i)->v4_addr;
snprintf(cmd, sizeof(cmd), "ip neighbor del %d.%d.%d.%d dev %s",
(unsigned char)(ipv4_addr >> 24), (unsigned char)(ipv4_addr >> 16),
(unsigned char)(ipv4_addr >> 8), (unsigned char)ipv4_addr, dev_name);
system(cmd);
IPACMDBG_H("%s\n", cmd);

/* First reset nat rules and then route rules */
if(get_client_memptr(eth_client, i)->ipv4_set == true)
{
Expand Down
2 changes: 1 addition & 1 deletion data-ipa-cfg-mgr/ipacm/src/IPACM_Neighbor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void IPACM_Neighbor::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("IPA_WLAN_CLIENT_ADD_EVENT_EX: not supported iface id: %d\n", data->if_index);
break;
}
uint8_t client_mac_addr[6] = {0};
uint8_t client_mac_addr[6];

IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
for(i = 0; i < data->num_of_attribs; i++)
Expand Down
56 changes: 5 additions & 51 deletions data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ IPACM_Wan::IPACM_Wan(int iface_index,
is_xlat = false;
hdr_hdl_dummy_v6 = 0;
hdr_proc_hdl_dummy_v6 = 0;
is_default_gateway = false;
m_fd_ipa = 0;
wan_client_len = 0;

if(iface_query != NULL)
{
Expand Down Expand Up @@ -714,13 +711,6 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
{
ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
ipa_interface_index = iface_ipa_index_query(data->if_index);
/* add the check see if tether_iface is valid or not */
if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
{
IPACMERR("UPSTREAM_ROUTE_ADD tether_if(%d), not valid ignore\n", INVALID_IFACE);
return;
}

if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype);
Expand Down Expand Up @@ -818,13 +808,6 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
{
ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
ipa_interface_index = iface_ipa_index_query(data->if_index);
/* add the check see if tether_iface is valid or not */
if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
{
IPACMERR("UPSTREAM_ROUTE_DEL tether_if(%d), not valid ignore\n", INVALID_IFACE);
return;
}

if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n");
Expand Down Expand Up @@ -4291,8 +4274,7 @@ int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4,
int IPACM_Wan::handle_down_evt()
{
int res = IPACM_SUCCESS;
int i, tether_total;
int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES];
int i;

IPACMDBG_H(" wan handle_down_evt \n");

Expand All @@ -4313,50 +4295,22 @@ int IPACM_Wan::handle_down_evt()
/* make sure default routing rules and firewall rules are deleted*/
if (active_v4)
{
if (rx_prop != NULL)
{
if (rx_prop != NULL)
{
del_dft_firewall_rules(IPA_IP_v4);
}
handle_route_del_evt(IPA_IP_v4);
IPACMDBG_H("Delete default v4 routing rules\n");
#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
/* posting wan_down_tether for all lan clients */
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
}
tether_total = IPACM_Wan::ipa_if_num_tether_v4_total;
for (i=0; i < tether_total; i++)
{
post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]);
IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n", i,
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
}

if (active_v6)
{
if (rx_prop != NULL)
{
if (rx_prop != NULL)
{
del_dft_firewall_rules(IPA_IP_v6);
}
handle_route_del_evt(IPA_IP_v6);
IPACMDBG_H("Delete default v6 routing rules\n");
#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
/* posting wan_down_tether for all lan clients */
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
}
tether_total = IPACM_Wan::ipa_if_num_tether_v6_total;
for (i=0; i < tether_total; i++)
{
post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]);
IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n", i,
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
}

/* Delete default v4 RT rule */
Expand Down
3 changes: 1 addition & 2 deletions data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index)
num_wifi_client = 0;
header_name_count = 0;
wlan_client = NULL;
wlan_client_len = 0;

if(iface_query != NULL)
{
Expand Down Expand Up @@ -1260,7 +1259,7 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
rt_rule_entry->rule.hashable = true;
#endif
if (false == m_routing.AddRoutingRule(rt_rule))
{
Expand Down

0 comments on commit 46f6547

Please sign in to comment.