John Lo | 55bf5c9 | 2016-07-04 23:23:32 -0400 | [diff] [blame] | 1 | From 38e154305ee5fd2ee454c19218ca144ffd1535f1 Mon Sep 17 00:00:00 2001 |
| 2 | From: John Daley <johndale@cisco.com> |
| 3 | Date: Sat, 11 Jun 2016 10:27:04 -0700 |
| 4 | Subject: [PATCH 21/25] net/enic: fix crash when releasing queues |
| 5 | |
| 6 | If device configuration failed due to a lack of resources, such as |
| 7 | if more queues are requested than are available, the queue release |
| 8 | functions are called with NULL pointers which were being dereferenced. |
| 9 | |
| 10 | Skip releasing queues if they are NULL pointers. |
| 11 | |
| 12 | Fixes: fefed3d1e62c ("enic: new driver") |
| 13 | |
| 14 | Signed-off-by: John Daley <johndale@cisco.com> |
| 15 | --- |
| 16 | drivers/net/enic/enic_main.c | 21 ++++++++++++++++----- |
| 17 | 1 file changed, 16 insertions(+), 5 deletions(-) |
| 18 | |
| 19 | diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c |
| 20 | index 56ec96e..4e5594f 100644 |
| 21 | --- a/drivers/net/enic/enic_main.c |
| 22 | +++ b/drivers/net/enic/enic_main.c |
| 23 | @@ -462,9 +462,15 @@ int enic_alloc_intr_resources(struct enic *enic) |
| 24 | |
| 25 | void enic_free_rq(void *rxq) |
| 26 | { |
| 27 | - struct vnic_rq *rq_sop = (struct vnic_rq *)rxq; |
| 28 | - struct enic *enic = vnic_dev_priv(rq_sop->vdev); |
| 29 | - struct vnic_rq *rq_data = &enic->rq[rq_sop->data_queue_idx]; |
| 30 | + struct vnic_rq *rq_sop, *rq_data; |
| 31 | + struct enic *enic; |
| 32 | + |
| 33 | + if (rxq == NULL) |
| 34 | + return; |
| 35 | + |
| 36 | + rq_sop = (struct vnic_rq *)rxq; |
| 37 | + enic = vnic_dev_priv(rq_sop->vdev); |
| 38 | + rq_data = &enic->rq[rq_sop->data_queue_idx]; |
| 39 | |
| 40 | enic_rxmbuf_queue_release(enic, rq_sop); |
| 41 | if (rq_data->in_use) |
| 42 | @@ -657,9 +663,14 @@ err_exit: |
| 43 | |
| 44 | void enic_free_wq(void *txq) |
| 45 | { |
| 46 | - struct vnic_wq *wq = (struct vnic_wq *)txq; |
| 47 | - struct enic *enic = vnic_dev_priv(wq->vdev); |
| 48 | + struct vnic_wq *wq; |
| 49 | + struct enic *enic; |
| 50 | + |
| 51 | + if (txq == NULL) |
| 52 | + return; |
| 53 | |
| 54 | + wq = (struct vnic_wq *)txq; |
| 55 | + enic = vnic_dev_priv(wq->vdev); |
| 56 | rte_memzone_free(wq->cqmsg_rz); |
| 57 | vnic_wq_free(wq); |
| 58 | vnic_cq_free(&enic->cq[enic->rq_count + wq->index]); |
| 59 | -- |
| 60 | 2.7.0 |
| 61 | |