qcacmn: Fix buffer overflow in process_tx_info and process_rx_info

Currently data in "pl_tgt_hdr" is used directly from firmware without
any length check which may cause buffer over-read.

To address this issue add length check before accessing data offset

Change-Id: Ic2930fdf7168b79a8522be282b0e1cd19214742a
CRs-Fixed: 2191170
此提交包含在:
jitiphil
2018-02-16 19:18:25 +05:30
提交者 nshrivas
父節點 974da2640a
當前提交 0081d767f1
共有 3 個檔案被更改,包括 505 行新增66 行删除

查看文件

@@ -865,18 +865,21 @@ int pktlog_clearbuff(struct hif_opaque_softc *scn, bool clear_buff)
*
* Return: None
*/
void pktlog_process_fw_msg(uint32_t *buff)
void pktlog_process_fw_msg(uint32_t *buff, uint32_t len)
{
uint32_t *pl_hdr;
uint32_t log_type;
struct cdp_pdev *pdev = get_txrx_context();
struct ol_fw_data pl_fw_data;
if (!pdev) {
qdf_print("%s: txrx_pdev is NULL", __func__);
return;
}
pl_hdr = buff;
pl_fw_data.data = pl_hdr;
pl_fw_data.len = len;
log_type =
(*(pl_hdr + 1) & ATH_PKTLOG_HDR_LOG_TYPE_MASK) >>
ATH_PKTLOG_HDR_LOG_TYPE_SHIFT;
@@ -887,19 +890,19 @@ void pktlog_process_fw_msg(uint32_t *buff)
|| (log_type == PKTLOG_TYPE_TX_FRM_HDR)
|| (log_type == PKTLOG_TYPE_TX_VIRT_ADDR))
wdi_event_handler(WDI_EVENT_TX_STATUS,
pdev, pl_hdr);
pdev, &pl_fw_data);
else if (log_type == PKTLOG_TYPE_RC_FIND)
wdi_event_handler(WDI_EVENT_RATE_FIND,
pdev, pl_hdr);
pdev, &pl_fw_data);
else if (log_type == PKTLOG_TYPE_RC_UPDATE)
wdi_event_handler(WDI_EVENT_RATE_UPDATE,
pdev, pl_hdr);
pdev, &pl_fw_data);
else if (log_type == PKTLOG_TYPE_RX_STAT)
wdi_event_handler(WDI_EVENT_RX_DESC,
pdev, pl_hdr);
pdev, &pl_fw_data);
else if (log_type == PKTLOG_TYPE_SW_EVENT)
wdi_event_handler(WDI_EVENT_SW_EVENT,
pdev, pl_hdr);
pdev, &pl_fw_data);
}
#if defined(QCA_WIFI_3_0_ADRASTEA)
@@ -926,6 +929,7 @@ static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt)
struct pktlog_dev_t *pdev = (struct pktlog_dev_t *)context;
qdf_nbuf_t pktlog_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
uint32_t *msg_word;
uint32_t msg_len;
/* check for sanity of the packet, have seen corrupted pkts */
if (pktlog_nbuf_check_sanity(pktlog_t2h_msg)) {
@@ -948,7 +952,8 @@ static void pktlog_t2h_msg_handler(void *context, HTC_PACKET *pkt)
qdf_assert((((unsigned long)qdf_nbuf_data(pktlog_t2h_msg)) & 0x3) == 0);
msg_word = (uint32_t *) qdf_nbuf_data(pktlog_t2h_msg);
pktlog_process_fw_msg(msg_word);
msg_len = qdf_nbuf_len(pktlog_t2h_msg);
pktlog_process_fw_msg(msg_word, msg_len);
qdf_nbuf_free(pktlog_t2h_msg);
}