[PATCH 10/32] wcn36xx: Use mem_to_flex_dup() with struct wcn36xx_hal_ind_msg

Kees Cook
2022-05-04T01:49:23Z

As part of the work to perform bounds checking on all memcpy() uses,
replace the open-coded a deserialization of bytes out of memory into a
trailing flexible array by using a flex_array.h helper to perform the
allocation, bounds checking, and copying.

Cc: Loic Poulain <loic.poulain@linaro.org>
Cc: Kalle Valo <kvalo@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: wcn36xx@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/net/wireless/ath/wcn36xx/smd.c | 8 ++------
drivers/net/wireless/ath/wcn36xx/smd.h | 4 ++--
2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index dc3805609284..106af0a2ffc4 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -3343,7 +3343,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
const struct wcn36xx_hal_msg_header *msg_header = buf;
struct ieee80211_hw *hw = priv;
struct wcn36xx *wcn = hw->priv;
- struct wcn36xx_hal_ind_msg *msg_ind;
+ struct wcn36xx_hal_ind_msg *msg_ind = NULL;
wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);

switch (msg_header->msg_type) {
@@ -3407,16 +3407,12 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
case WCN36XX_HAL_PRINT_REG_INFO_IND:
case WCN36XX_HAL_SCAN_OFFLOAD_IND:
- msg_ind = kmalloc(struct_size(msg_ind, msg, len), GFP_ATOMIC);
- if (!msg_ind) {
+ if (mem_to_flex_dup(&msg_ind, buf, len, GFP_ATOMIC)) {
wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
msg_header->msg_type);
return -ENOMEM;
}

- msg_ind->msg_len = len;
- memcpy(msg_ind->msg, buf, len);
-
spin_lock(&wcn->hal_ind_lock);
list_add_tail(&msg_ind->list, &wcn->hal_ind_queue);
queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 3fd598ac2a27..76ecac46f36b 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -46,8 +46,8 @@ struct wcn36xx_fw_msg_status_rsp {

struct wcn36xx_hal_ind_msg {
struct list_head list;
- size_t msg_len;
- u8 msg[];
+ DECLARE_FLEX_ARRAY_ELEMENTS_COUNT(size_t, msg_len);
+ DECLARE_FLEX_ARRAY_ELEMENTS(u8, msg);
};

struct wcn36xx;
--
2.32.0