diff options
author | Utkarsh Saxena <usaxena@codeaurora.org> | 2016-08-22 23:10:42 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-05 22:23:30 -0700 |
commit | e4aebe9d4c98463d485ef224d8f9a32d25c36830 (patch) | |
tree | 1c1736d91cf2908e742d48852466b2f99d3e88bd /ipanat | |
parent | 7b7d16a11a6777b0ade69b6dc8fb33915ec03d67 (diff) | |
download | ipacfg-mgr-e4aebe9d4c98463d485ef224d8f9a32d25c36830.tar.gz |
ipacm: Fix race condition between nat delete and update timestamp
NAT delete functionality and Update timestamp can run in two
separate threads in parallel.
Add pthread mutex lock around this two functions to avoid
race condition while accessing the NAT table memory.
Change-Id: I6d40ae6dbe3aa9ed840c2daae8555701baa91ef2
Diffstat (limited to 'ipanat')
-rw-r--r-- | ipanat/inc/ipa_nat_drvi.h | 1 | ||||
-rw-r--r-- | ipanat/src/ipa_nat_drvi.c | 52 |
2 files changed, 47 insertions, 6 deletions
diff --git a/ipanat/inc/ipa_nat_drvi.h b/ipanat/inc/ipa_nat_drvi.h index 002c025..6f9b1bd 100644 --- a/ipanat/inc/ipa_nat_drvi.h +++ b/ipanat/inc/ipa_nat_drvi.h @@ -39,6 +39,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <netinet/in.h> #include <sys/inotify.h> #include <errno.h> +#include <pthread.h> #include "ipa_nat_logi.h" diff --git a/ipanat/src/ipa_nat_drvi.c b/ipanat/src/ipa_nat_drvi.c index cfda3e3..faa8c8c 100644 --- a/ipanat/src/ipa_nat_drvi.c +++ b/ipanat/src/ipa_nat_drvi.c @@ -36,6 +36,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif struct ipa_nat_cache ipv4_nat_cache; +pthread_mutex_t nat_mutex = PTHREAD_MUTEX_INITIALIZER; /* ------------------------------------------ UTILITY FUNCTIONS START @@ -904,7 +905,13 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl) if (!ipv4_nat_cache.ip4_tbl[index].valid) { IPAERR("invalid table handle passed\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; + } + + if (pthread_mutex_lock(&nat_mutex) != 0) { + ret = -1; + goto lock_mutex_fail; } /* unmap the device memory from user space */ @@ -918,7 +925,10 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl) /* close the file descriptor of nat device */ if (close(ipv4_nat_cache.ip4_tbl[index].nat_fd)) { IPAERR("unable to close the file descriptor\n"); - return -EINVAL; + ret = -EINVAL; + if (pthread_mutex_unlock(&nat_mutex) != 0) + goto unlock_mutex_fail; + goto fail; } del_cmd.table_index = index; @@ -928,9 +938,12 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl) perror("ipa_nati_del_ipv4_table(): ioctl error value"); IPAERR("unable to post nat del command init Error: %d\n", ret); IPADBG("ipa fd %d\n", ipv4_nat_cache.ipa_fd); - return -EINVAL; + ret = -EINVAL; + if (pthread_mutex_unlock(&nat_mutex) != 0) + goto unlock_mutex_fail; + goto fail; } - IPADBG("posted IPA_IOC_V4_DEL_NAT to kernel successfully\n"); + IPAERR("posted IPA_IOC_V4_DEL_NAT to kernel successfully\n"); free(ipv4_nat_cache.ip4_tbl[index].index_expn_table_meta); free(ipv4_nat_cache.ip4_tbl[index].rule_id_array); @@ -942,7 +955,22 @@ int ipa_nati_del_ipv4_table(uint32_t tbl_hdl) /* Decrease the table count by 1*/ ipv4_nat_cache.table_cnt--; + if (pthread_mutex_unlock(&nat_mutex) != 0) { + ret = -1; + goto unlock_mutex_fail; + } + return 0; + +lock_mutex_fail: + IPAERR("unable to lock the nat mutex\n"); + return ret; + +unlock_mutex_fail: + IPAERR("unable to unlock the nat mutex\n"); + +fail: + return ret; } int ipa_nati_query_timestamp(uint32_t tbl_hdl, @@ -959,6 +987,11 @@ int ipa_nati_query_timestamp(uint32_t tbl_hdl, return -EINVAL; } + if (pthread_mutex_lock(&nat_mutex) != 0) { + IPAERR("unable to lock the nat mutex\n"); + return -1; + } + ipa_nati_parse_ipv4_rule_hdl(tbl_index, (uint16_t)rule_hdl, &expn_tbl, &tbl_entry); @@ -969,8 +1002,15 @@ int ipa_nati_query_timestamp(uint32_t tbl_hdl, (struct ipa_nat_rule *)ipv4_nat_cache.ip4_tbl[tbl_index].ipv4_expn_rules_addr; } - *time_stamp = Read32BitFieldValue(tbl_ptr[tbl_entry].ts_proto, - TIME_STAMP_FIELD); + if (tbl_ptr) + *time_stamp = Read32BitFieldValue(tbl_ptr[tbl_entry].ts_proto, + TIME_STAMP_FIELD); + + if (pthread_mutex_unlock(&nat_mutex) != 0) { + IPAERR("unable to unlock the nat mutex\n"); + return -1; + } + return 0; } |