gpu: nvgpu: fix access-out-of-bounds issue

As part of the function gp10b_clk_get_freqs, the code walksthrough
the H/W frequency table and populates the gp10b_freq_table by picking
only GP10B_NUM_SUPPORTED_FREQS =
 GP10B_MAX_SUPPORTED_FREQS/GP10B_FREQ_SELECT_STEP frequencies at max.

The access-out-of-bounds happen when sel_freq_count reaches
GP10B_NUM_SUPPORTED_FREQS and new_rate equals max_rate, resulting
in one additional update that is beyond the size of gp10b_freq_table
table.

Also, removed the warning as it will never be true.

Bug 3407276

Change-Id: Ic496ccdda1784130e7139bd93d068be58eb60a35
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2617850
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Debarshi Dutta
2021-10-28 10:43:55 +05:30
committed by mobile promotions
parent d60bcde892
commit e616b2ba4d

View File

@@ -56,12 +56,15 @@
/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */
#define GP10B_FREQ_SELECT_STEP 8
/* Allow limited set of frequencies to be available */
#define GP10B_NUM_SUPPORTED_FREQS 15
/* Max number of freq supported in h/w */
#define GP10B_MAX_SUPPORTED_FREQS 120
/* Allow limited set of frequencies to be available */
#define GP10B_NUM_SUPPORTED_FREQS ((GP10B_MAX_SUPPORTED_FREQS) / (GP10B_FREQ_SELECT_STEP))
static unsigned long
gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS / GP10B_FREQ_SELECT_STEP];
gp10b_freq_table[GP10B_NUM_SUPPORTED_FREQS];
static bool freq_table_init_complete;
static int num_supported_freq;
@@ -481,19 +484,18 @@ int gp10b_clk_get_freqs(struct device *dev,
* add MAX freq to last
*/
sel_freq_cnt = 0;
for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; ++i) {
for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS &&
sel_freq_cnt < GP10B_NUM_SUPPORTED_FREQS; ++i) {
new_rate = loc_freq_table[i];
if (i % GP10B_FREQ_SELECT_STEP == 0 ||
if ((i % GP10B_FREQ_SELECT_STEP == 0) ||
new_rate == max_rate) {
gp10b_freq_table[sel_freq_cnt++] =
new_rate;
gp10b_freq_table[sel_freq_cnt++] = new_rate;
if (new_rate == max_rate)
break;
}
}
WARN_ON(sel_freq_cnt == GP10B_MAX_SUPPORTED_FREQS);
}
/* Fill freq table */