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;
