From: Ilias Apalodimas <[email protected]>

Fixes: https://bugs.linaro.org/show_bug.cgi?id=3182 by adding proper
checks on allocated memory.

Signed-off-by: Ilias Apalodimas <[email protected]>
---
/** Email created from pull request 101 (apalos:bug_3182)
 ** https://github.com/Linaro/odp/pull/101
 ** Patch: https://github.com/Linaro/odp/pull/101.patch
 ** Base sha: 4537d096721a753086592ed5a989beab5647bcfa
 ** Merge commit sha: 7bee8312cef61d52ce1c788583f3831f05afcfeb
 **/
 platform/linux-generic/odp_pkt_queue.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/platform/linux-generic/odp_pkt_queue.c 
b/platform/linux-generic/odp_pkt_queue.c
index 7c6cd87e..06420a96 100644
--- a/platform/linux-generic/odp_pkt_queue.c
+++ b/platform/linux-generic/odp_pkt_queue.c
@@ -85,17 +85,27 @@ static queue_blk_t *blk_idx_to_queue_blk(queue_pool_t 
*queue_pool,
        return &queue_region_desc->queue_blks->blks[blk_tbl_idx];
 }
 
+static void free_alloced_queue_blks(uint32_t end, queue_blks_t *blk_array[])
+{
+       uint32_t i;
+
+       for (i = 0; i < end; i++)
+               free(blk_array[i]);
+}
+
 static int pkt_queue_free_list_add(queue_pool_t *pool,
                                   uint32_t num_queue_blks)
 {
        queue_region_desc_t *region_desc;
        queue_blks_t *queue_blks;
+       queue_blks_t *alloced_queue_blks[num_queue_blks];
        queue_blk_t *queue_blk;
        uint32_t which_region, blks_added, num_blks, start_idx;
-       uint32_t malloc_len, blks_to_add, cnt, i;
+       uint32_t malloc_len, blks_to_add, cnt, i, alloc_cnt;
 
        which_region = pool->current_region;
        blks_added = 0;
+       alloc_cnt = 0;
        while ((blks_added < num_queue_blks) && (pool->all_regions_used == 0)) {
                region_desc = &pool->queue_region_descs[which_region];
                start_idx = region_desc->next_blk_idx;
@@ -104,6 +114,13 @@ static int pkt_queue_free_list_add(queue_pool_t *pool,
                if (!queue_blks) {
                        malloc_len = num_blks * sizeof(queue_blk_t);
                        queue_blks = malloc(malloc_len);
+                       if (!queue_blks) {
+                               free_alloced_queue_blks(alloc_cnt,
+                                                       alloced_queue_blks);
+                               return -1;
+                       }
+                       alloced_queue_blks[alloc_cnt] = queue_blks;
+                       alloc_cnt++;
 
                        for (i = 0; i < num_blks; i++)
                                init_queue_blk(&queue_blks->blks[i]);
@@ -194,8 +211,19 @@ _odp_int_queue_pool_t _odp_queue_pool_create(uint32_t 
max_num_queues,
        int rc;
 
        pool = malloc(sizeof(queue_pool_t));
+       if (!pool)
+               return _ODP_INT_QUEUE_POOL_INVALID;
+
        memset(pool, 0, sizeof(queue_pool_t));
 
+       malloc_len = max_num_queues * sizeof(uint32_t);
+       pool->queue_num_tbl = malloc(malloc_len);
+       if (!pool->queue_num_tbl)  {
+               free(pool);
+               return _ODP_INT_QUEUE_POOL_INVALID;
+       }
+       memset(pool->queue_num_tbl, 0, malloc_len);
+
        /* Initialize the queue_blk_tbl_sizes array based upon the
        * max_queued_pkts.
        */
@@ -223,10 +251,6 @@ _odp_int_queue_pool_t _odp_queue_pool_create(uint32_t 
max_num_queues,
        pool->max_queued_pkts = max_queued_pkts;
        pool->next_queue_num = 1;
 
-       malloc_len = max_num_queues * sizeof(uint32_t);
-       pool->queue_num_tbl = malloc(malloc_len);
-       memset(pool->queue_num_tbl, 0, malloc_len);
-
        pool->min_free_list_size = pool->free_list_size;
        pool->peak_free_list_size = pool->free_list_size;
        return (_odp_int_queue_pool_t)(uintptr_t)pool;

Reply via email to