[dpdk-dev,v4,1/2] enic: fix seg fault when releasing queues

Message ID 1465666025-10159-1-git-send-email-johndale@cisco.com (mailing list archive)
State Accepted, archived
Delegated to: Bruce Richardson
Headers

Commit Message

John Daley (johndale) June 11, 2016, 5:27 p.m. UTC
  If device configuration failed due to a lack of resources, such as
if more queues are requested than are available, the queue release
functions are called with NULL pointers which were being dereferenced.

Skip releasing queues if they are NULL pointers.

Fixes: fefed3d1e62c ("enic: new driver")
Signed-off-by: John Daley <johndale@cisco.com>
---

v4: fix check for NULL before pointer is set

 drivers/net/enic/enic_main.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
  

Comments

Bruce Richardson June 13, 2016, 2:23 p.m. UTC | #1
On Sat, Jun 11, 2016 at 10:27:04AM -0700, John Daley wrote:
> If device configuration failed due to a lack of resources, such as
> if more queues are requested than are available, the queue release
> functions are called with NULL pointers which were being dereferenced.
> 
> Skip releasing queues if they are NULL pointers.
> 
> Fixes: fefed3d1e62c ("enic: new driver")
> Signed-off-by: John Daley <johndale@cisco.com>
Patchset applied to dpdk-next-net/rel_16_07

/Bruce
  

Patch

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 996f999..738792e 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -426,9 +426,14 @@  int enic_alloc_intr_resources(struct enic *enic)
 
 void enic_free_rq(void *rxq)
 {
-	struct vnic_rq *rq = (struct vnic_rq *)rxq;
-	struct enic *enic = vnic_dev_priv(rq->vdev);
+	struct vnic_rq *rq;
+	struct enic *enic;
 
+	if (rxq == NULL)
+		return;
+
+	rq = (struct vnic_rq *)rxq;
+	enic = vnic_dev_priv(rq->vdev);
 	enic_rxmbuf_queue_release(enic, rq);
 	rte_free(rq->mbuf_ring);
 	rq->mbuf_ring = NULL;
@@ -514,9 +519,14 @@  err_exit:
 
 void enic_free_wq(void *txq)
 {
-	struct vnic_wq *wq = (struct vnic_wq *)txq;
-	struct enic *enic = vnic_dev_priv(wq->vdev);
+	struct vnic_wq *wq;
+	struct enic *enic;
+
+	if (txq == NULL)
+		return;
 
+	wq = (struct vnic_wq *)txq;
+	enic = vnic_dev_priv(wq->vdev);
 	rte_memzone_free(wq->cqmsg_rz);
 	vnic_wq_free(wq);
 	vnic_cq_free(&enic->cq[enic->rq_count + wq->index]);