wifi: mwifiex: Refactor 1-element array into flexible array in struct mwifiex_ie_type...
authorKees Cook <keescook@chromium.org>
Wed, 7 Feb 2024 10:30:33 +0000 (02:30 -0800)
committerKalle Valo <kvalo@kernel.org>
Mon, 12 Feb 2024 15:37:59 +0000 (17:37 +0200)
struct mwifiex_ie_types_chan_list_param_set::chan_scan_param is treated
as a flexible array, so convert it into one so that it doesn't trip
the array bounds sanitizer[1]. Only a few places were using sizeof()
on the whole struct, so adjust those to follow the calculation pattern
to avoid including the trailing single element.

Examining binary output differences doesn't appear to show any literal
size values changing, though it is obfuscated a bit by the compiler
adjusting register usage and stack spill slots, etc.

Link: https://github.com/KSPP/linux/issues/51
Cc: Brian Norris <briannorris@chromium.org>
Cc: Kalle Valo <kvalo@kernel.org>
Cc: Dmitry Antipov <dmantipov@yandex.ru>
Cc: Johannes Berg <johannes.berg@intel.com>
Cc: zuoqilin <zuoqilin@yulong.com>
Cc: Ruan Jinjie <ruanjinjie@huawei.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Cc: linux-wireless@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240207103024.make.423-kees@kernel.org
drivers/net/wireless/marvell/mwifiex/11n.c
drivers/net/wireless/marvell/mwifiex/fw.h
drivers/net/wireless/marvell/mwifiex/scan.c

index 90e4011..c0c635e 100644 (file)
@@ -392,12 +392,10 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
 
                chan_list =
                        (struct mwifiex_ie_types_chan_list_param_set *) *buffer;
-               memset(chan_list, 0,
-                      sizeof(struct mwifiex_ie_types_chan_list_param_set));
+               memset(chan_list, 0, struct_size(chan_list, chan_scan_param, 1));
                chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
-               chan_list->header.len = cpu_to_le16(
-                       sizeof(struct mwifiex_ie_types_chan_list_param_set) -
-                       sizeof(struct mwifiex_ie_types_header));
+               chan_list->header.len =
+                       cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
                chan_list->chan_scan_param[0].chan_number =
                        bss_desc->bcn_ht_oper->primary_chan;
                chan_list->chan_scan_param[0].radio_type =
@@ -411,8 +409,8 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
                                          (bss_desc->bcn_ht_oper->ht_param &
                                          IEEE80211_HT_PARAM_CHA_SEC_OFFSET));
 
-               *buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set);
-               ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set);
+               *buffer += struct_size(chan_list, chan_scan_param, 1);
+               ret_len += struct_size(chan_list, chan_scan_param, 1);
        }
 
        if (bss_desc->bcn_bss_co_2040) {
index 62f3c9a..3adc447 100644 (file)
@@ -770,7 +770,7 @@ struct mwifiex_chan_scan_param_set {
 
 struct mwifiex_ie_types_chan_list_param_set {
        struct mwifiex_ie_types_header header;
-       struct mwifiex_chan_scan_param_set chan_scan_param[1];
+       struct mwifiex_chan_scan_param_set chan_scan_param[];
 } __packed;
 
 struct mwifiex_ie_types_rxba_sync {
index a2ddac3..0326b12 100644 (file)
@@ -664,15 +664,14 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
 
                        /* Copy the current channel TLV to the command being
                           prepared */
-                       memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
+                       memcpy(&chan_tlv_out->chan_scan_param[tlv_idx],
                               tmp_chan_list,
-                              sizeof(chan_tlv_out->chan_scan_param));
+                              sizeof(*chan_tlv_out->chan_scan_param));
 
                        /* Increment the TLV header length by the size
                           appended */
                        le16_unaligned_add_cpu(&chan_tlv_out->header.len,
-                                              sizeof(
-                                               chan_tlv_out->chan_scan_param));
+                                              sizeof(*chan_tlv_out->chan_scan_param));
 
                        /*
                         * The tlv buffer length is set to the number of bytes
@@ -2369,12 +2368,11 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
                     chan_idx < MWIFIEX_BG_SCAN_CHAN_MAX &&
                     bgscan_cfg_in->chan_list[chan_idx].chan_number;
                     chan_idx++) {
-                       temp_chan = chan_list_tlv->chan_scan_param + chan_idx;
+                       temp_chan = &chan_list_tlv->chan_scan_param[chan_idx];
 
                        /* Increment the TLV header length by size appended */
                        le16_unaligned_add_cpu(&chan_list_tlv->header.len,
-                                              sizeof(
-                                              chan_list_tlv->chan_scan_param));
+                                              sizeof(*chan_list_tlv->chan_scan_param));
 
                        temp_chan->chan_number =
                                bgscan_cfg_in->chan_list[chan_idx].chan_number;
@@ -2413,7 +2411,7 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
                                                           chan_scan_param);
                le16_unaligned_add_cpu(&chan_list_tlv->header.len,
                                       chan_num *
-                            sizeof(chan_list_tlv->chan_scan_param[0]));
+                            sizeof(*chan_list_tlv->chan_scan_param));
        }
 
        tlv_pos += (sizeof(chan_list_tlv->header)