qcacld-3.0: fix a possible out-of-bounds access issue

The array size of 'channels' in struct channel_list_info
is CFG_VALID_CHANNEL_LIST_LEN, which may smaller than
NUM_CHANNELS, function 'iw_get_channel_list()' may attempt
to access element CFG_VALID_CHANNEL_LIST_LEN..NUM_CHANNELS
of array 'channels'.
To make align, fix array size of 'channels' to NUM_CHANNELS,
and refine 'iw_get_channel_list_with_cc()'.

CRs-Fixed: 2777780
Change-Id: Ie064322f14186310a769db2642e69c8a520f1b26
This commit is contained in:
Yu Wang 2020-09-18 13:34:56 +08:00 • committed by snandini
commit f7b5dced13
2 changed files with 13 additions and 7 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -29,7 +29,7 @@
struct channel_list_info {
uint8_t num_channels;
uint8_t channels[CFG_VALID_CHANNEL_LIST_LEN];
uint8_t channels[NUM_CHANNELS];
};
#ifdef __linux__

View file

@ -1990,19 +1990,25 @@ int iw_get_channel_list_with_cc(struct net_device *dev,
hdd_err_rl("GetChannelList Failed!!!");
return -EINVAL;
}
buf = extra;
/*
* Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN.
* Maximum buffer needed = 5 * number of channels.
* Maximum buffer needed =
* [4: 3 digits of num_chn + 1 space] +
* [REG_ALPHA2_LEN: REG_ALPHA2_LEN digits] +
* [4 * num_chn: (1 space + 3 digits of chn[i]) * num_chn] +
* [1: Terminator].
*
* Check if sufficient buffer is available and then
* proceed to fill the buffer.
*/
if (WE_MAX_STR_LEN < (5 * CFG_VALID_CHANNEL_LIST_LEN)) {
if (WE_MAX_STR_LEN <
(4 + REG_ALPHA2_LEN + 4 * channel_list.num_channels + 1)) {
hdd_err_rl("Insufficient Buffer to populate channel list");
return -EINVAL;
}
len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", channel_list.num_channels);
buf = extra;
len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", channel_list.num_channels);
wlan_reg_get_cc_and_src(mac->psoc, ubuf);
/* Printing Country code in getChannelList(break at '\0') */
for (i = 0; i < (ubuf_len - 1) && ubuf[i] != 0; i++)