Unregister callback on cleanup to avoid use after free from the
interrupt thread (eal_intr_thread_main).

To be more defensive, set ptr to NULL if we can unregister.

rte_intr_callback_unregister_sync may (optionally) use traces
so the alarm cleanup must happen before eal_trace_fini to avoid
accessing freed memory.

Bugzilla ID: 1683

Signed-off-by: Rui Ferreira <rui.ferrei...@h-partners.com>
---
 lib/eal/freebsd/eal.c       | 3 ++-
 lib/eal/freebsd/eal_alarm.c | 8 +++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c
index d6fffa2170..21ce4e6b18 100644
--- a/lib/eal/freebsd/eal.c
+++ b/lib/eal/freebsd/eal.c
@@ -907,8 +907,9 @@ rte_eal_cleanup(void)
        rte_mp_channel_cleanup();
        eal_bus_cleanup();
        rte_trace_save();
-       eal_trace_fini();
+       /* may use trace, must be called before eal_trace_fini */
        rte_eal_alarm_cleanup();
+       eal_trace_fini();
        /* after this point, any DPDK pointers will become dangling */
        rte_eal_memory_detach();
        eal_cleanup_config(internal_conf);
diff --git a/lib/eal/freebsd/eal_alarm.c b/lib/eal/freebsd/eal_alarm.c
index 28f285fdef..c03e281e67 100644
--- a/lib/eal/freebsd/eal_alarm.c
+++ b/lib/eal/freebsd/eal_alarm.c
@@ -50,7 +50,13 @@ static void eal_alarm_callback(void *arg);
 void
 rte_eal_alarm_cleanup(void)
 {
-       rte_intr_instance_free(intr_handle);
+       /* unregister callback using intr_handle in interrupt thread */
+       int ret = rte_intr_callback_unregister_sync(intr_handle,
+                       eal_alarm_callback, (void *)-1);
+       if (ret >= 0) {
+               rte_intr_instance_free(intr_handle);
+               intr_handle = NULL;
+       }
 }
 
 int
-- 
2.43.0

Reply via email to