From: Vsevolod Stakhov Date: Wed, 25 Aug 2021 15:41:47 +0000 (+0100) Subject: [Fix] Add concept of uncancellable events to prevent use-after-free X-Git-Tag: 3.1~221 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9d809fc59320afe0304d2e7194a5a68067fb60d2;p=rspamd.git [Fix] Add concept of uncancellable events to prevent use-after-free --- diff --git a/src/libserver/async_session.c b/src/libserver/async_session.c index 1bd4c77e9..057604447 100644 --- a/src/libserver/async_session.c +++ b/src/libserver/async_session.c @@ -278,20 +278,30 @@ rspamd_session_cleanup (struct rspamd_async_session *session) } session->flags |= RSPAMD_SESSION_FLAG_CLEANUP; + khash_t(rspamd_events_hash) *uncancellable_events = kh_init(rspamd_events_hash); kh_foreach_key (session->events, ev, { /* Call event's finalizer */ - msg_debug_session ("removed event on destroy: %p, subsystem: %s", - ev->user_data, - ev->subsystem); + int ret; if (ev->fin != NULL) { + msg_debug_session ("removed event on destroy: %p, subsystem: %s", + ev->user_data, + ev->subsystem); ev->fin (ev->user_data); } + else { + msg_debug_session ("NOT removed event on destroy - uncancellable: %p, subsystem: %s", + ev->user_data, + ev->subsystem); + /* Assume an event is uncancellable, move it to a new hash table */ + kh_put (rspamd_events_hash, uncancellable_events, ev, &ret); + } }); - kh_clear (rspamd_events_hash, session->events); - + kh_destroy (rspamd_events_hash, session->events); + session->events = uncancellable_events; + msg_debug_session ("pending %d uncancellable events", kh_size (uncancellable_events)); session->flags &= ~RSPAMD_SESSION_FLAG_CLEANUP; }