76 lines
2.2 KiB
Diff
76 lines
2.2 KiB
Diff
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 <christian.ehrhardt@canonical.com>
|
|
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);
|
|
}
|