Description: lpm/lpm6: fix use after free and missing frees In certain autotests lpm->max_rules turned out to be non initialized. Also lpm6 autotests failed with the default alloc of 512M Memory. While >=2500M was a workaround it became clear while debugging that it had a leak. That eventually led to the identification of various use after free and leaks in the lpm/lpm6 code. Along that is also makes the RTE_LOG messages of the failed allocation unique. The patches are upstream accepted in 4 pieces now. This combines them plus a minor tweak currently in review at http://dpdk.org/dev/patchwork/patch/12025/ Forwarded: Yes - accepted 768f0e45 732a5b5c 34c4b584 d4c18f0a Author: Christian Ehrhardt Last-Update: 2016-04-12 Index: dpdk/lib/librte_lpm/rte_lpm.c =================================================================== --- dpdk.orig/lib/librte_lpm/rte_lpm.c +++ dpdk/lib/librte_lpm/rte_lpm.c @@ -236,13 +236,10 @@ rte_lpm_free(struct rte_lpm *lpm) if (te->data == (void *) lpm) break; } - if (te == NULL) { - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); - return; + if (te != NULL) { + TAILQ_REMOVE(lpm_list, te, next); } - TAILQ_REMOVE(lpm_list, te, next); - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); rte_free(lpm); Index: dpdk/lib/librte_lpm/rte_lpm6.c =================================================================== --- dpdk.orig/lib/librte_lpm/rte_lpm6.c +++ dpdk/lib/librte_lpm/rte_lpm6.c @@ -206,8 +206,9 @@ rte_lpm6_create(const char *name, int so (size_t)rules_size, RTE_CACHE_LINE_SIZE, socket_id); if (lpm->rules_tbl == NULL) { - RTE_LOG(ERR, LPM, "LPM memory allocation failed\n"); + RTE_LOG(ERR, LPM, "LPM rules_tbl allocation failed\n"); rte_free(lpm); + lpm = NULL; rte_free(te); goto exit; } @@ -277,15 +278,14 @@ rte_lpm6_free(struct rte_lpm6 *lpm) if (te->data == (void *) lpm) break; } - if (te == NULL) { - rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); - return; - } - TAILQ_REMOVE(lpm_list, te, next); + if (te != NULL) { + TAILQ_REMOVE(lpm_list, te, next); + } rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK); + rte_free(lpm->rules_tbl); rte_free(lpm); rte_free(te); }