mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-20 21:34:24 -05:00
140 lines
5.4 KiB
Diff
140 lines
5.4 KiB
Diff
|
From 3fabdcba3a09ce8f3cc757bf6240e53421a1e363 Mon Sep 17 00:00:00 2001
|
||
|
From: Srinivas Girigowda <sgirigow@codeaurora.org>
|
||
|
Date: Fri, 4 Aug 2017 15:51:34 -0700
|
||
|
Subject: [PATCH] qcacld-2.0: Check target address boundary before access
|
||
|
|
||
|
Athdiag procfs entry does not have address sanity check, this is
|
||
|
resulting in invalid ioread32/iowrite32 if out of PCIE BAR address
|
||
|
is used.
|
||
|
|
||
|
Fix this by allowing address with in PCIE BAR range.
|
||
|
|
||
|
Change-Id: I8365eacca7ccc4f489b7d0bda6c998384d0fec7b
|
||
|
CRs-Fixed: 2062012
|
||
|
Bug: 62058746
|
||
|
Signed-off-by: Srinivas Girigowda <sgirigow@codeaurora.org>
|
||
|
---
|
||
|
.../staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h | 8 +++++++
|
||
|
.../qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c | 26 ++++++++++++++++++++++
|
||
|
.../qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c | 1 +
|
||
|
.../qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h | 2 +-
|
||
|
.../qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c | 9 ++++++--
|
||
|
5 files changed, 43 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h
|
||
|
index a3c31afe3bd67..06a02eebc1be5 100644
|
||
|
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h
|
||
|
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/hif.h
|
||
|
@@ -880,4 +880,12 @@ static inline void hif_request_runtime_pm_resume(void *ol_sc)
|
||
|
|
||
|
A_BOOL HIFIsMailBoxSwapped(HIF_DEVICE *hd);
|
||
|
|
||
|
+#ifdef HIF_PCI
|
||
|
+int hif_addr_in_boundary(HIF_DEVICE *hif_device, A_UINT32 offset);
|
||
|
+#else
|
||
|
+static inline int hif_addr_in_boundary(HIF_DEVICE *hif_device, A_UINT32 offset)
|
||
|
+{
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+#endif
|
||
|
#endif /* _HIF_H_ */
|
||
|
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c
|
||
|
index 3a1de9d23d07a..ba33ac976305a 100644
|
||
|
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c
|
||
|
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/hif_pci.c
|
||
|
@@ -3628,3 +3628,29 @@ bool hif_is_80211_fw_wow_required(void)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
+
|
||
|
+/* hif_addr_in_boundary() - API to check if addr is with in PCIE BAR range
|
||
|
+ * @hif_device: context of cd
|
||
|
+ * @offset: offset from PCI BAR mapped base address.
|
||
|
+ *
|
||
|
+ * API determines if address to be accessed is with in range or out
|
||
|
+ * of bound.
|
||
|
+ *
|
||
|
+ * Return: success if address is with in PCI BAR range.
|
||
|
+ */
|
||
|
+int hif_addr_in_boundary(HIF_DEVICE *hif_device, A_UINT32 offset)
|
||
|
+{
|
||
|
+ struct HIF_CE_state *hif_state;
|
||
|
+ struct hif_pci_softc *sc;
|
||
|
+
|
||
|
+ hif_state = (struct HIF_CE_state *)hif_device;
|
||
|
+ sc = hif_state->sc;
|
||
|
+ if (unlikely(offset + sizeof(unsigned int) > sc->mem_len)) {
|
||
|
+ VOS_TRACE(VOS_MODULE_ID_HIF, VOS_TRACE_LEVEL_ERROR,
|
||
|
+ "refusing to read mmio out of bounds at 0x%08x - 0x%08zx (max 0x%08zx)\n",
|
||
|
+ offset, offset + sizeof(unsigned int), sc->mem_len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
|
||
|
index 17792cd6460e4..0d5fd226f5275 100644
|
||
|
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
|
||
|
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.c
|
||
|
@@ -1589,6 +1589,7 @@ hif_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||
|
|
||
|
OS_MEMZERO(sc, sizeof(*sc));
|
||
|
sc->mem = mem;
|
||
|
+ sc->mem_len = pci_resource_len(pdev, BAR_NUM);
|
||
|
sc->pdev = pdev;
|
||
|
sc->dev = &pdev->dev;
|
||
|
|
||
|
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h
|
||
|
index 3204f6101eb9d..ea0e22d3d1a80 100644
|
||
|
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h
|
||
|
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/PCIe/if_pci.h
|
||
|
@@ -82,7 +82,7 @@ struct hif_pci_pm_stats {
|
||
|
struct hif_pci_softc {
|
||
|
void __iomem *mem; /* PCI address. */
|
||
|
/* For efficiency, should be first in struct */
|
||
|
-
|
||
|
+ size_t mem_len;
|
||
|
struct device *dev;
|
||
|
struct pci_dev *pdev;
|
||
|
struct _NIC_DEV aps_osdev;
|
||
|
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
|
||
|
index ed0cfd69d7228..d1a34dd6c3966 100644
|
||
|
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
|
||
|
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
|
||
|
@@ -90,13 +90,16 @@ static ssize_t ath_procfs_diag_read(struct file *file, char __user *buf,
|
||
|
int rv;
|
||
|
A_UINT8 *read_buffer = NULL;
|
||
|
|
||
|
+ hif_hdl = get_hif_hdl_from_file(file);
|
||
|
+ if (hif_addr_in_boundary(hif_hdl, (A_UINT32)(*pos)))
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
read_buffer = (A_UINT8 *)vos_mem_malloc(count);
|
||
|
if (NULL == read_buffer) {
|
||
|
pr_debug("%s: vos_mem_alloc failed\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
- hif_hdl = get_hif_hdl_from_file(file);
|
||
|
pr_debug("rd buff 0x%p cnt %zu offset 0x%x buf 0x%p\n",
|
||
|
read_buffer,count,
|
||
|
(int)*pos, buf);
|
||
|
@@ -129,6 +132,9 @@ static ssize_t ath_procfs_diag_write(struct file *file, const char __user *buf,
|
||
|
int rv;
|
||
|
A_UINT8 *write_buffer = NULL;
|
||
|
|
||
|
+ hif_hdl = get_hif_hdl_from_file(file);
|
||
|
+ if (hif_addr_in_boundary(hif_hdl, (A_UINT32)(*pos)))
|
||
|
+ return -EINVAL;
|
||
|
write_buffer = (A_UINT8 *)vos_mem_malloc(count);
|
||
|
if (NULL == write_buffer) {
|
||
|
pr_debug("%s: vos_mem_alloc failed\n", __func__);
|
||
|
@@ -139,7 +145,6 @@ static ssize_t ath_procfs_diag_write(struct file *file, const char __user *buf,
|
||
|
return -EFAULT;
|
||
|
}
|
||
|
|
||
|
- hif_hdl = get_hif_hdl_from_file(file);
|
||
|
pr_debug("wr buff 0x%p buf 0x%p cnt %zu offset 0x%x value 0x%x\n",
|
||
|
write_buffer, buf, count,
|
||
|
(int)*pos, *((A_UINT32 *)write_buffer));
|