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 90e40110089812d97f78fb6d3719f6c1ec9fd44a..c0c635e74bc5051eafb55c66fe0d8e1528bcfef5 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 62f3c9a52a1d5c1536107e2d466945aca50e6c21..3adc447b715f6861b53e55f484b325eb2f074cfe 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 a2ddac363b1005f1b2863f5721a476d181273421..0326b121747cb2a729077017ef437022c797c2fc 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)