summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCNSS_WLAN Service <cnssbldsw@qualcomm.com>2019-04-23 18:58:26 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-04-23 18:58:26 -0700
commit11fdab25545b45ce9977d5d49618eaa7f93098ae (patch)
tree490edf0360977791e363905ef468a4c244d885e9
parent01f644635fea868e046c0ea0915c85f5452af684 (diff)
parent203db8efc8e285d9c3a417a693fa424a7daa3a72 (diff)
Merge "qcacld-2.0: Fix buffer overflow in process_rx_info etc" into wlan-cld2.driver.lnx.1.0
-rw-r--r--CORE/UTILS/PKTLOG/pktlog_internal.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/CORE/UTILS/PKTLOG/pktlog_internal.c b/CORE/UTILS/PKTLOG/pktlog_internal.c
index 689204978da6..2db9e9f685ff 100644
--- a/CORE/UTILS/PKTLOG/pktlog_internal.c
+++ b/CORE/UTILS/PKTLOG/pktlog_internal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -546,11 +546,33 @@ process_rx_info(void *pdev, void *data)
struct ath_pktlog_hdr pl_hdr;
size_t log_size;
uint32_t *pl_tgt_hdr;
+ struct ol_fw_data *fw_data;
+ uint32_t len;
if (!pdev) {
printk("Invalid pdev in %s", __func__);
return A_ERROR;
}
+
+ fw_data = (struct ol_fw_data *)data;
+ len = fw_data->len;
+ if (len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_TIMESTAMP_OFFSET + 1))) {
+ adf_os_print("Invalid msdu len in %s\n", __func__);
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
+ data = fw_data->data;
+
pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev;
pl_info = pl_dev->pl_info;
pl_tgt_hdr = (uint32_t *)data;
@@ -567,6 +589,12 @@ process_rx_info(void *pdev, void *data)
ATH_PKTLOG_HDR_SIZE_MASK) >>
ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
+
+ if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
log_size = pl_hdr.size;
rxstat_log.rx_desc = (void *)pktlog_getbuf(pl_dev, pl_info,
log_size, &pl_hdr);
@@ -593,6 +621,8 @@ process_rate_find(void *pdev, void *data)
*/
struct ath_pktlog_rc_find rcf_log;
uint32_t *pl_tgt_hdr;
+ struct ol_fw_data *fw_data;
+ uint32_t len;
if (!pdev) {
adf_os_print("Invalid pdev in %s\n", __func__);
@@ -603,6 +633,25 @@ process_rate_find(void *pdev, void *data)
return A_ERROR;
}
+ fw_data = (struct ol_fw_data *)data;
+ len = fw_data->len;
+ if (len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_TIMESTAMP_OFFSET + 1))) {
+ adf_os_print("Invalid msdu len in %s\n", __func__);
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
+ data = fw_data->data;
+
pl_tgt_hdr = (uint32_t *)data;
/*
* Makes the short words (16 bits) portable b/w little endian
@@ -621,6 +670,12 @@ process_rate_find(void *pdev, void *data)
ATH_PKTLOG_HDR_SIZE_MASK) >>
ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
+
+ if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev;
pl_info = pl_dev->pl_info;
log_size = pl_hdr.size;
@@ -643,6 +698,8 @@ process_rate_update(void *pdev, void *data)
struct ath_pktlog_info *pl_info;
struct ath_pktlog_rc_update rcu_log;
uint32_t *pl_tgt_hdr;
+ struct ol_fw_data *fw_data;
+ uint32_t len;
if (!pdev) {
printk("Invalid pdev in %s\n", __func__);
@@ -652,6 +709,26 @@ process_rate_update(void *pdev, void *data)
printk("Invalid data in %s\n", __func__);
return A_ERROR;
}
+
+ fw_data = (struct ol_fw_data *)data;
+ len = fw_data->len;
+ if (len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_FLAGS_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_MISSED_CNT_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_LOG_TYPE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_SIZE_OFFSET + 1)) ||
+ len < (sizeof(uint32_t) *
+ (ATH_PKTLOG_HDR_TIMESTAMP_OFFSET + 1))) {
+ adf_os_print("Invalid msdu len in %s\n", __func__);
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
+ data = fw_data->data;
+
pl_tgt_hdr = (uint32_t *)data;
/*
* Makes the short words (16 bits) portable b/w little endian
@@ -670,6 +747,12 @@ process_rate_update(void *pdev, void *data)
ATH_PKTLOG_HDR_SIZE_MASK) >>
ATH_PKTLOG_HDR_SIZE_SHIFT;
pl_hdr.timestamp = *(pl_tgt_hdr + ATH_PKTLOG_HDR_TIMESTAMP_OFFSET);
+
+ if (sizeof(struct ath_pktlog_hdr) + pl_hdr.size > len) {
+ adf_os_assert(0);
+ return A_ERROR;
+ }
+
pl_dev = ((struct ol_txrx_pdev_t *) pdev)->pl_dev;
log_size = pl_hdr.size;
pl_info = pl_dev->pl_info;