From 0cd1793ba552bccf085487352463cb513afd9cd9 Mon Sep 17 00:00:00 2001 From: Tallapragada Kalyan Date: Fri, 23 Jun 2017 11:16:42 +0530 Subject: [PATCH] qcacmn: fix skb cb corruption issue the ftype in skb->cb is overshooting allocated 48 bytes causing kernel crash Change-Id: Ie33508c462a032b28624de5270ce91a93d0b067d --- dp/wifi3.0/dp_rx.c | 8 ++++---- qdf/inc/qdf_nbuf.h | 6 ++++++ qdf/linux/src/i_qdf_nbuf.h | 17 +++++++++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index a52de638c7bb..102acd2f6de1 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -350,8 +350,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) { memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); len = qdf_nbuf_len(nbuf); - qdf_nbuf_set_fctx_type(nbuf, (void *)NULL, - CB_FTYPE_INTRABSS_FWD); + qdf_nbuf_set_ftype(nbuf, CB_FTYPE_INTRABSS_FWD); + if (!dp_tx_send(sa_peer->vdev, nbuf)) { DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts, 1, len); @@ -378,8 +378,8 @@ dp_rx_intrabss_fwd(struct dp_soc *soc, return false; memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb)); len = qdf_nbuf_len(nbuf_copy); - qdf_nbuf_set_fctx_type(nbuf_copy, (void *)NULL, - CB_FTYPE_INTRABSS_FWD); + qdf_nbuf_set_ftype(nbuf_copy, CB_FTYPE_INTRABSS_FWD); + if (dp_tx_send(sa_peer->vdev, nbuf_copy)) { DP_STATS_INC_PKT(sa_peer, rx.intra_bss.fail, 1, len); qdf_nbuf_free(nbuf_copy); diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 15f9d030ebd0..5c93e66a41a7 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -559,6 +559,12 @@ qdf_nbuf_set_vdev_ctx(qdf_nbuf_t buf, void *vdev_ctx) __qdf_nbuf_set_vdev_ctx(buf, vdev_ctx); } +static inline void +qdf_nbuf_set_ftype(qdf_nbuf_t buf, uint8_t type) +{ + __qdf_nbuf_set_ftype(buf, type); +} + static inline void qdf_nbuf_set_fctx_type(qdf_nbuf_t buf, void *ctx, uint8_t type) { diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index e42ef5b2ea34..54d2379f5b9a 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -196,9 +196,9 @@ struct qdf_nbuf_cb { } trace; /* 4 bytes */ uint32_t submit_ts; } u; + uint8_t ftype; void *fctx; void *vdev_ctx; - uint8_t ftype; } win; /* 21 bytes*/ struct { uint32_t data_attr; /* 4 bytes */ @@ -220,7 +220,8 @@ struct qdf_nbuf_cb { priv:31; } ipa; /* 4 */ uint16_t desc_id; /* 2 bytes */ - } mcl;/* 14 bytes*/ + uint8_t ftype; /*1 byte */ + } mcl;/* 15 bytes*/ } dev; } tx; /* 40 bytes */ } u; @@ -309,8 +310,6 @@ struct qdf_nbuf_cb { #define QDF_NBUF_CB_TX_IPA_PRIV(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.mcl.ipa.priv) -#define QDF_NBUF_CB_TX_FTYPE(skb) \ - (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.win.ftype) #define QDF_NBUF_CB_TX_FCTX(skb) \ (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.win.fctx) @@ -360,6 +359,8 @@ struct qdf_nbuf_cb { #define QDF_NBUF_CB_SET_MCAST(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.tx.dev.mcl.trace.is_mcast = true) +#define QDF_NBUF_CB_TX_FTYPE(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.mcl.ftype) #else @@ -416,6 +417,9 @@ struct qdf_nbuf_cb { #define QDF_NBUF_CB_SET_MCAST(skb) \ (((struct qdf_nbuf_cb *) \ ((skb)->cb))->u.tx.dev.win.u.trace.is_mcast = true) + +#define QDF_NBUF_CB_TX_FTYPE(skb) \ + (((struct qdf_nbuf_cb *)((skb)->cb))->u.tx.dev.win.ftype) #endif /* assume the OS provides a single fragment */ @@ -492,6 +496,11 @@ typedef void (*qdf_nbuf_free_t)(__qdf_nbuf_t); #define __qdf_nbuf_get_vdev_ctx(skb) \ QDF_NBUF_CB_TX_VDEV_CTX((skb)) +#define __qdf_nbuf_set_ftype(skb, type) \ + do { \ + QDF_NBUF_CB_TX_FTYPE((skb)) = (type); \ + } while (0) + #define __qdf_nbuf_set_fctx_type(skb, ctx, type) \ do { \ QDF_NBUF_CB_TX_FCTX((skb)) = (ctx); \