| From foo@baz Sat Apr 16 22:36:37 PDT 2016 |
| From: Arnd Bergmann <arnd@arndb.de> |
| Date: Mon, 14 Mar 2016 15:18:36 +0100 |
| Subject: ath9k: fix buffer overrun for ar9287 |
| Status: RO |
| Content-Length: 2787 |
| Lines: 65 |
| |
| From: Arnd Bergmann <arnd@arndb.de> |
| |
| [ Upstream commit 83d6f1f15f8cce844b0a131cbc63e444620e48b5 ] |
| |
| Code that was added back in 2.6.38 has an obvious overflow |
| when accessing a static array, and at the time it was added |
| only a code comment was put in front of it as a reminder |
| to have it reviewed properly. |
| |
| This has not happened, but gcc-6 now points to the specific |
| overflow: |
| |
| drivers/net/wireless/ath/ath9k/eeprom.c: In function 'ath9k_hw_get_gain_boundaries_pdadcs': |
| drivers/net/wireless/ath/ath9k/eeprom.c:483:44: error: array subscript is above array bounds [-Werror=array-bounds] |
| maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4]; |
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ |
| |
| It turns out that the correct array length exists in the local |
| 'intercepts' variable of this function, so we can just use that |
| instead of hardcoding '4', so this patch changes all three |
| instances to use that variable. The other two instances were |
| already correct, but it's more consistent this way. |
| |
| Signed-off-by: Arnd Bergmann <arnd@arndb.de> |
| Fixes: 940cd2c12ebf ("ath9k_hw: merge the ar9287 version of ath9k_hw_get_gain_boundaries_pdadcs") |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/wireless/ath/ath9k/eeprom.c | 7 +++---- |
| 1 file changed, 3 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/net/wireless/ath/ath9k/eeprom.c |
| +++ b/drivers/net/wireless/ath/ath9k/eeprom.c |
| @@ -408,10 +408,9 @@ void ath9k_hw_get_gain_boundaries_pdadcs |
| |
| if (match) { |
| if (AR_SREV_9287(ah)) { |
| - /* FIXME: array overrun? */ |
| for (i = 0; i < numXpdGains; i++) { |
| minPwrT4[i] = data_9287[idxL].pwrPdg[i][0]; |
| - maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4]; |
| + maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1]; |
| ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
| data_9287[idxL].pwrPdg[i], |
| data_9287[idxL].vpdPdg[i], |
| @@ -421,7 +420,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs |
| } else if (eeprom_4k) { |
| for (i = 0; i < numXpdGains; i++) { |
| minPwrT4[i] = data_4k[idxL].pwrPdg[i][0]; |
| - maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4]; |
| + maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1]; |
| ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
| data_4k[idxL].pwrPdg[i], |
| data_4k[idxL].vpdPdg[i], |
| @@ -431,7 +430,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs |
| } else { |
| for (i = 0; i < numXpdGains; i++) { |
| minPwrT4[i] = data_def[idxL].pwrPdg[i][0]; |
| - maxPwrT4[i] = data_def[idxL].pwrPdg[i][4]; |
| + maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1]; |
| ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i], |
| data_def[idxL].pwrPdg[i], |
| data_def[idxL].vpdPdg[i], |