wcn36xx_smd_process_ptt_msg_rsp() uses rsp->header.len (firmware-reported total message length including the header) as the kmemdup size when copying the PTT message payload. Since the copy starts at rsp->ptt_msg, which is at offset sizeof(*rsp) (12 bytes) within the response buffer, this reads 12 bytes beyond the actual message data. The debug dump has a similar issue: it uses rsp->header.len minus only sizeof(ptt_msg_resp_status) (4 bytes), reading 8 bytes past the data. Both cases read stale data from the hal_buf (a 4096-byte heap buffer), and kmemdup returns it to the testmode caller which passes it to userspace via netlink, constituting an information leak. Fix by computing the PTT payload length from the verified buffer length rather than trusting the firmware-reported header.len field, and add an explicit check that the buffer is large enough for the response header. Fixes: 87f825e6e246 ("wcn36xx: Add support for Factory Test Mode (FTM)") Cc: stable@vger.kernel.org Signed-off-by: Aamir Ahmed --- drivers/net/wireless/ath/wcn36xx/smd.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index c0b477345832..d8597bc112f0 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -1066,21 +1066,26 @@ static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len, void **p_ptt_rsp_msg) { struct wcn36xx_hal_process_ptt_msg_rsp_msg *rsp; + size_t ptt_msg_len; int ret; ret = wcn36xx_smd_rsp_status_check(buf, len); if (ret) return ret; + if (len < sizeof(*rsp)) + return -EIO; + rsp = buf; + ptt_msg_len = len - sizeof(*rsp); - wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n", - rsp->header.len); + wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %zu\n", + ptt_msg_len); wcn36xx_dbg_dump(WCN36XX_DBG_HAL_DUMP, "HAL_PTT_MSG_RSP:", rsp->ptt_msg, - rsp->header.len - sizeof(rsp->ptt_msg_resp_status)); + ptt_msg_len); - if (rsp->header.len > 0) { - *p_ptt_rsp_msg = kmemdup(rsp->ptt_msg, rsp->header.len, + if (ptt_msg_len > 0) { + *p_ptt_rsp_msg = kmemdup(rsp->ptt_msg, ptt_msg_len, GFP_ATOMIC); if (!*p_ptt_rsp_msg) return -ENOMEM; -- 2.43.0