mmc: msm_sdcc: fix possible buffer overflow
If "total_phases" argument of find_most_appropriate_phase()
function have value greater than 16, it may cause the
out bound access for arrays used within this function.
So this patch validates the value of "total_phases" to
avoid buffer overflow.
Change-Id: I0519066b37595e1ee2121b77965b119cfd995eb4
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index e364eac..0d2b11d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2877,15 +2877,22 @@
* Select the 3/4 of the range and configure the DLL with the
* selected DLL clock output phase.
*/
-static u8 find_most_appropriate_phase(struct msmsdcc_host *host,
+static int find_most_appropriate_phase(struct msmsdcc_host *host,
u8 *phase_table, u8 total_phases)
{
- u8 ret, ranges[16][16] = { {0}, {0} };
+ int ret;
+ u8 ranges[16][16] = { {0}, {0} };
u8 phases_per_row[16] = {0};
int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
bool phase_0_found = false, phase_15_found = false;
+ if (total_phases > 16) {
+ pr_err("%s: %s: invalid argument: total_phases=%d\n",
+ mmc_hostname(host->mmc), __func__, total_phases);
+ return -EINVAL;
+ }
+
for (cnt = 0; cnt < total_phases; cnt++) {
ranges[row_index][col_index] = phase_table[cnt];
phases_per_row[row_index] += 1;
@@ -2943,7 +2950,7 @@
}
i = ((curr_max * 3) / 4) - 1;
- ret = ranges[selected_row_index][i];
+ ret = (int)ranges[selected_row_index][i];
return ret;
}
@@ -3022,8 +3029,13 @@
} while (++phase < 16);
if (tuned_phase_cnt) {
- phase = find_most_appropriate_phase(host, tuned_phases,
+ rc = find_most_appropriate_phase(host, tuned_phases,
tuned_phase_cnt);
+ if (rc < 0)
+ goto kfree;
+ else
+ phase = (u8)rc;
+
/*
* Finally set the selected phase in delay
* line hw block.