diff options
Diffstat (limited to 'drivers/net/wireless/bcmdhd/dhd_cdc.c')
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_cdc.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c index 33ebeb559059..820bbade720c 100644 --- a/drivers/net/wireless/bcmdhd/dhd_cdc.c +++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_cdc.c 353370 2012-08-27 09:10:22Z $ + * $Id: dhd_cdc.c 355825 2012-09-10 03:22:40Z $ * * BDC is like CDC, except it includes a header for data packets to convey * packet priority over the bus, and flags (e.g. to indicate checksum status @@ -854,6 +854,12 @@ _dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf) /* pull BDC header */ PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN); + + if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) { + WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__, + PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2))); + return BCME_ERROR; + } /* pull wl-header */ PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2)); return BCME_OK; @@ -916,7 +922,15 @@ _dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx, } else { /* remove header first */ - _dhd_wlfc_pullheader(ctx, p); + rc = _dhd_wlfc_pullheader(ctx, p); + if (rc != BCME_OK) { + WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__)); + /* free the hanger slot */ + dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1); + PKTFREE(ctx->osh, p, TRUE); + rc = BCME_ERROR; + return rc; + } if (pkt_type == eWLFC_PKTTYPE_DELAYED) { /* delay-q packets are going to delay-q */ @@ -1166,16 +1180,17 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx, int gen; /* remove old header */ - _dhd_wlfc_pullheader(ctx, p); - - hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); + rc = _dhd_wlfc_pullheader(ctx, p); + if (rc == BCME_OK) { + hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen); - WLFC_PKTFLAG_SET_GENERATION(htod, gen); - free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); - /* push new header */ - _dhd_wlfc_pushheader(ctx, p, send_tim_update, - entry->traffic_lastreported_bmp, entry->mac_handle, htod); + WLFC_PKTFLAG_SET_GENERATION(htod, gen); + free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p))); + /* push new header */ + _dhd_wlfc_pushheader(ctx, p, send_tim_update, + entry->traffic_lastreported_bmp, entry->mac_handle, htod); + } } *slot = hslot; return rc; |