diff options
| author | Mingcheng Zhu <mingchen@qca.qualcomm.com> | 2014-08-22 13:23:32 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-08-29 15:50:31 -0700 |
| commit | fe7b871241bdb5503a01deaa795a290adaf621c7 (patch) | |
| tree | cf668c9b16072a60d6848cf94eedf0a1a430022c | |
| parent | 65751509f6367e1a7daafb11d42e3be51ef95eca (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.c | 8 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/copy_engine_api.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/hif_pci.c | 9 |
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); |
