]> granicus.if.org Git - libevent/commitdiff
Fix a use-after-free error on EV_CLOSURE_EVENT_FINALIZE callbacks
authorNick Mathewson <nickm@torproject.org>
Tue, 18 Mar 2014 15:25:58 +0000 (11:25 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 18 Mar 2014 15:27:08 +0000 (11:27 -0400)
After running the callback, we were checking evcb->evcb_closure to
decide whether to call mm_free(ev).  But the callback itself might
have freed ev, so we need to grab that field first

Found with AddressSanitizer

event.c

diff --git a/event.c b/event.c
index 0c4b30b6236e90eab353f3fc7433cc8f51113490..a5e8d0b1e9914f24802bad14be191eb42b5a8fc6 100644 (file)
--- a/event.c
+++ b/event.c
@@ -1584,6 +1584,7 @@ event_process_active_single_queue(struct event_base *base,
                case EV_CLOSURE_EVENT_FINALIZE:
                case EV_CLOSURE_EVENT_FINALIZE_FREE: {
                        void (*evcb_evfinalize)(struct event *, void *);
+                       int evcb_closure = evcb->evcb_closure;
                        EVUTIL_ASSERT(ev != NULL);
                        base->current_event = NULL;
                        evcb_evfinalize = ev->ev_evcallback.evcb_cb_union.evcb_evfinalize;
@@ -1591,7 +1592,7 @@ event_process_active_single_queue(struct event_base *base,
                        EVBASE_RELEASE_LOCK(base, th_base_lock);
                        evcb_evfinalize(ev, ev->ev_arg);
                        event_debug_note_teardown_(ev);
-                       if (evcb->evcb_closure == EV_CLOSURE_EVENT_FINALIZE_FREE)
+                       if (evcb_closure == EV_CLOSURE_EVENT_FINALIZE_FREE)
                                mm_free(ev);
                }
                break;