summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMingcheng Zhu <mingchen@qca.qualcomm.com>2014-08-22 13:23:32 -0700
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-08-29 15:50:31 -0700
commitfe7b871241bdb5503a01deaa795a290adaf621c7 (patch)
treecf668c9b16072a60d6848cf94eedf0a1a430022c
parent65751509f6367e1a7daafb11d42e3be51ef95eca (diff)
WLAN: Fix a buffer write overflow
Array write overflow happens and fixed here. Change-Id: I1bbb45ba0e4cc52f186900a68caeb3e094cf0309 CRs-Fixed: 715653
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine.c8
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine_api.h2
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c9
3 files changed, 14 insertions, 5 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c
index b6cf8f4fc3d2..abb53b641571 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine.c
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c
@@ -233,7 +233,7 @@ CE_sendlist_init(struct CE_sendlist *sendlist)
sl->num_items=0;
}
-void
+int
CE_sendlist_buf_add(struct CE_sendlist *sendlist,
CE_addr_t buffer,
unsigned int nbytes,
@@ -243,7 +243,10 @@ CE_sendlist_buf_add(struct CE_sendlist *sendlist,
unsigned int num_items = sl->num_items;
struct CE_sendlist_item *item;
- A_ASSERT(num_items < CE_SENDLIST_ITEMS_MAX);
+ if (num_items >= CE_SENDLIST_ITEMS_MAX) {
+ A_ASSERT(num_items < CE_SENDLIST_ITEMS_MAX);
+ return A_NO_RESOURCE;
+ }
item = &sl->item[num_items];
item->send_type = CE_SIMPLE_BUFFER_TYPE;
@@ -251,6 +254,7 @@ CE_sendlist_buf_add(struct CE_sendlist *sendlist,
item->u.nbytes = nbytes;
item->flags = flags;
sl->num_items = num_items+1;
+ return A_OK;
}
int
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine_api.h b/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
index 1aaea6d8dee2..bc865fd92495 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
@@ -169,7 +169,7 @@ unsigned int CE_sendlist_sizeof(void);
void CE_sendlist_init(struct CE_sendlist *sendlist);
/* Append a simple buffer (address/length) to a sendlist. */
-void CE_sendlist_buf_add(struct CE_sendlist *sendlist,
+int CE_sendlist_buf_add(struct CE_sendlist *sendlist,
CE_addr_t buffer,
unsigned int nbytes,
u_int32_t flags /* OR-ed with internal flags */);
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 342a56919346..c819226cff7e 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -287,7 +287,6 @@ HIFSend_head(HIF_DEVICE *hif_device,
struct CE_sendlist sendlist;
int status;
-
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n",__FUNCTION__));
A_ASSERT(nbytes <= adf_nbuf_len(nbuf));
@@ -306,11 +305,17 @@ HIFSend_head(HIF_DEVICE *hif_device,
frag_paddr = adf_nbuf_get_frag_paddr_lo(nbuf, nfrags);
frag_bytes = adf_nbuf_get_frag_len(nbuf, nfrags);
- CE_sendlist_buf_add(
+ status = CE_sendlist_buf_add(
&sendlist, frag_paddr,
frag_bytes > bytes ? bytes : frag_bytes,
adf_nbuf_get_frag_is_wordstream(nbuf, nfrags) ?
0 : CE_SEND_FLAG_SWAP_DISABLE);
+ if (status != A_OK) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s: error, frag_num %d larger than the given limit\n",
+ __func__, nfrags));
+ return status;
+ }
bytes -= frag_bytes;
nfrags++;
} while (bytes > 0);