event/octeontx2: fix null dereference
authorPavan Nikhilesh <pbhagavatula@marvell.com>
Wed, 24 Jul 2019 12:06:34 +0000 (17:36 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 29 Jul 2019 20:17:29 +0000 (22:17 +0200)
Fix NULL dereference after rte_realloc and add extra NULL checks.
Fix few memory leak with kvargs.

Coverity issue: 345023, 345022, 345009, 345011, 345026, 344997, 344990
Fixes: ffa4ec0b6063 ("event/octeontx2: allow adapters to resize inflight buffers")

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
drivers/event/octeontx2/otx2_evdev.c
drivers/event/octeontx2/otx2_evdev_adptr.c
drivers/event/octeontx2/otx2_tim_evdev.c

index e6379e3..160ac94 100644 (file)
@@ -1404,7 +1404,12 @@ sso_xae_reconfigure(struct rte_eventdev *event_dev)
 
        prev_xaq_pool = dev->xaq_pool;
        dev->xaq_pool = NULL;
-       sso_xaq_allocate(dev);
+       rc = sso_xaq_allocate(dev);
+       if (rc < 0) {
+               otx2_err("Failed to alloc xaq pool %d", rc);
+               rte_mempool_free(prev_xaq_pool);
+               return rc;
+       }
        rc = sso_ggrp_alloc_xaq(dev);
        if (rc < 0) {
                otx2_err("Failed to alloc xaq to ggrp %d", rc);
@@ -1517,6 +1522,7 @@ parse_queue_param(char *value, void *opaque)
        uint8_t *val = (uint8_t *)&queue_qos;
        struct otx2_sso_evdev *dev = opaque;
        char *tok = strtok(value, "-");
+       struct otx2_sso_qos *old_ptr;
 
        if (!strlen(value))
                return;
@@ -1533,9 +1539,15 @@ parse_queue_param(char *value, void *opaque)
        }
 
        dev->qos_queue_cnt++;
+       old_ptr = dev->qos_parse_data;
        dev->qos_parse_data = rte_realloc(dev->qos_parse_data,
                                          sizeof(struct otx2_sso_qos) *
                                          dev->qos_queue_cnt, 0);
+       if (dev->qos_parse_data == NULL) {
+               dev->qos_parse_data = old_ptr;
+               dev->qos_queue_cnt--;
+               return;
+       }
        dev->qos_parse_data[dev->qos_queue_cnt - 1] = queue_qos;
 }
 
@@ -1553,7 +1565,7 @@ parse_qos_list(const char *value, void *opaque)
                else if (*s == ']')
                        end = s;
 
-               if (start < end && *start) {
+               if (start && start < end) {
                        *end = 0;
                        parse_queue_param(start + 1, opaque);
                        s = end;
index 0c4f18e..b6e9f59 100644 (file)
@@ -203,6 +203,7 @@ sso_updt_xae_cnt(struct otx2_sso_evdev *dev, void *data, uint32_t event_type)
        {
                struct otx2_eth_rxq *rxq = data;
                int i, match = false;
+               uint64_t *old_ptr;
 
                for (i = 0; i < dev->rx_adptr_pool_cnt; i++) {
                        if ((uint64_t)rxq->pool == dev->rx_adptr_pools[i])
@@ -211,10 +212,17 @@ sso_updt_xae_cnt(struct otx2_sso_evdev *dev, void *data, uint32_t event_type)
 
                if (!match) {
                        dev->rx_adptr_pool_cnt++;
+                       old_ptr = dev->rx_adptr_pools;
                        dev->rx_adptr_pools = rte_realloc(dev->rx_adptr_pools,
                                                          sizeof(uint64_t) *
                                                          dev->rx_adptr_pool_cnt
                                                          , 0);
+                       if (dev->rx_adptr_pools == NULL) {
+                               dev->adptr_xae_cnt += rxq->pool->size;
+                               dev->rx_adptr_pools = old_ptr;
+                               dev->rx_adptr_pool_cnt--;
+                               return;
+                       }
                        dev->rx_adptr_pools[dev->rx_adptr_pool_cnt - 1] =
                                (uint64_t)rxq->pool;
 
index ecc7563..e8316a6 100644 (file)
@@ -549,6 +549,7 @@ tim_parse_ring_param(char *value, void *opaque)
        struct otx2_tim_evdev *dev = opaque;
        struct otx2_tim_ctl ring_ctl = {0};
        char *tok = strtok(value, "-");
+       struct otx2_tim_ctl *old_ptr;
        uint16_t *val;
 
        val = (uint16_t *)&ring_ctl;
@@ -569,8 +570,16 @@ tim_parse_ring_param(char *value, void *opaque)
        }
 
        dev->ring_ctl_cnt++;
+       old_ptr = dev->ring_ctl_data;
        dev->ring_ctl_data = rte_realloc(dev->ring_ctl_data,
-                       sizeof(struct otx2_tim_ctl), 0);
+                                        sizeof(struct otx2_tim_ctl) *
+                                        dev->ring_ctl_cnt, 0);
+       if (dev->ring_ctl_data == NULL) {
+               dev->ring_ctl_data = old_ptr;
+               dev->ring_ctl_cnt--;
+               return;
+       }
+
        dev->ring_ctl_data[dev->ring_ctl_cnt - 1] = ring_ctl;
 }
 
@@ -588,7 +597,7 @@ tim_parse_ring_ctl_list(const char *value, void *opaque)
                else if (*s == ']')
                        end = s;
 
-               if (start < end && *start) {
+               if (start && start < end) {
                        *end = 0;
                        tim_parse_ring_param(start + 1, opaque);
                        start = end;
@@ -635,6 +644,8 @@ tim_parse_devargs(struct rte_devargs *devargs, struct otx2_tim_evdev *dev)
                           &dev->min_ring_cnt);
        rte_kvargs_process(kvlist, OTX2_TIM_RING_CTL,
                           &tim_parse_kvargs_dict, &dev);
+
+       rte_kvargs_free(kvlist);
 }
 
 void