ipacm: Fix race condition between nat delete rule and update timestamp
NAT delete rule and Update timestamp can run in two
separate parallel threads.
Add pthread mutex lock around nat delete rule API to avoid
race condition while accessing the NAT table memory.
Change-Id: I66dac53f5f1831575d5f208519b70a3fbe802ca0
diff --git a/ipanat/src/ipa_nat_drvi.c b/ipanat/src/ipa_nat_drvi.c
index faa8c8c..9b96c44 100644
--- a/ipanat/src/ipa_nat_drvi.c
+++ b/ipanat/src/ipa_nat_drvi.c
@@ -1527,13 +1527,20 @@
struct ipa_nat_ip4_table_cache *tbl_ptr;
del_type rule_pos;
uint8_t tbl_indx = (uint8_t)(tbl_hdl - 1);
+ int ret;
/* Parse the rule handle */
ipa_nati_parse_ipv4_rule_hdl(tbl_indx, (uint16_t)rule_hdl,
&expn_tbl, &tbl_entry);
if (IPA_NAT_INVALID_NAT_ENTRY == tbl_entry) {
IPAERR("Invalid Rule Entry\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (pthread_mutex_lock(&nat_mutex) != 0) {
+ ret = -1;
+ goto mutex_lock_error;
}
IPADBG("Delete below rule\n");
@@ -1542,7 +1549,10 @@
tbl_ptr = &ipv4_nat_cache.ip4_tbl[tbl_indx];
if (!tbl_ptr->valid) {
IPAERR("invalid table handle\n");
- return -EINVAL;
+ ret = -EINVAL;
+ if (pthread_mutex_unlock(&nat_mutex) != 0)
+ goto mutex_unlock_error;
+ goto fail;
}
ipa_nati_find_rule_pos(tbl_ptr, expn_tbl,
@@ -1551,7 +1561,10 @@
if (ipa_nati_post_del_dma_cmd(tbl_indx, tbl_entry,
expn_tbl, rule_pos)) {
- return -EINVAL;
+ ret = -EINVAL;
+ if (pthread_mutex_unlock(&nat_mutex) != 0)
+ goto mutex_unlock_error;
+ goto fail;
}
ipa_nati_del_dead_ipv4_head_nodes(tbl_indx);
@@ -1565,7 +1578,22 @@
ipa_nat_dump_ipv4_table(tbl_hdl);
#endif
+ if (pthread_mutex_unlock(&nat_mutex) != 0) {
+ ret = -1;
+ goto mutex_unlock_error;
+ }
+
return 0;
+
+mutex_lock_error:
+ IPAERR("unable to lock the nat mutex\n");
+ return ret;
+
+mutex_unlock_error:
+ IPAERR("unable to unlock the nat mutex\n");
+
+fail:
+ return ret;
}
void ReorderCmds(struct ipa_ioc_nat_dma_cmd *cmd, int size)