From a78a593c7e9e26a6ecd4919b52eb849cc0eb19dd Mon Sep 17 00:00:00 2001 From: Mohammed Javid Date: Fri, 8 Jun 2018 16:55:32 +0530 Subject: [PATCH] msm: ipa3: Add mutex to prevent race condition There is a race condition between ipa3_nat_init_cmd and ipa_read_nat4. The two thread will R/W the critical global variables. This will result in race conditions and possibly buffer overread/ overwrite issues. Add code to prevent this race condition. Change-Id: I6bf9a837ae941cf3ad9413da6e44821916acf196 Acked-by: Pooja Kumari Signed-off-by: Mohammed Javid --- drivers/platform/msm/ipa/ipa_v2/ipa_nat.c | 13 +++++++++++++ drivers/platform/msm/ipa/ipa_v3/ipa_nat.c | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c index cc3d26764048..7f434a065fc6 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c @@ -327,14 +327,18 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) size_t tmp; gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0); + mutex_lock(&ipa_ctx->nat_mem.lock); + if (!ipa_ctx->nat_mem.is_dev_init) { IPAERR_RL("Nat table not initialized\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } IPADBG("\n"); if (init->table_entries == 0) { IPADBG("Table entries is zero\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -342,6 +346,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->ipv4_rules_offset > (UINT_MAX - (TBL_ENTRY_SIZE * (init->table_entries + 1)))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Table Entry offset is not @@ -353,6 +358,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->ipv4_rules_offset, (init->table_entries + 1), tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -360,6 +366,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->expn_rules_offset > UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries)) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table Entry offset is not @@ -371,6 +378,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->expn_rules_offset, init->expn_table_entries, tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -378,6 +386,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Indx Table Entry offset is not @@ -389,6 +398,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_offset, (init->table_entries + 1), tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -396,6 +406,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_expn_offset > (UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table entry offset is not @@ -407,6 +418,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_expn_offset, init->expn_table_entries, tmp, ipa_ctx->nat_mem.size); + mutex_unlock(&ipa_ctx->nat_mem.lock); return -EPERM; } @@ -555,6 +567,7 @@ free_mem: free_nop: kfree(reg_write_nop); bail: + mutex_unlock(&ipa_ctx->nat_mem.lock); return result; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c index 5f9cfc208854..17e4cae311ce 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c @@ -368,6 +368,9 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("Detected overflow\n"); return -EPERM; } + + mutex_lock(&ipa3_ctx->nat_mem.lock); + /* Check Table Entry offset is not beyond allocated size */ tmp = init->ipv4_rules_offset + @@ -377,6 +380,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->ipv4_rules_offset, (init->table_entries + 1), tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -384,6 +388,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->expn_rules_offset > (UINT_MAX - (TBL_ENTRY_SIZE * init->expn_table_entries))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table Entry offset is not @@ -395,6 +400,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->expn_rules_offset, init->expn_table_entries, tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -402,6 +408,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * (init->table_entries + 1))) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Indx Table Entry offset is not @@ -413,6 +420,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_offset, (init->table_entries + 1), tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -420,6 +428,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) if (init->index_expn_offset > UINT_MAX - (INDX_TBL_ENTRY_SIZE * init->expn_table_entries)) { IPAERR_RL("Detected overflow\n"); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } /* Check Expn Table entry offset is not @@ -431,6 +440,7 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR_RL("offset:%d entrys:%d size:%zu mem_size:%zu\n", init->index_expn_offset, init->expn_table_entries, tmp, ipa3_ctx->nat_mem.size); + mutex_unlock(&ipa3_ctx->nat_mem.lock); return -EPERM; } @@ -580,6 +590,7 @@ destroy_imm_cmd: free_nop: ipahal_destroy_imm_cmd(nop_cmd_pyld); bail: + mutex_unlock(&ipa3_ctx->nat_mem.lock); return result; } -- 2.11.0