]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Add concept of uncancellable events to prevent use-after-free
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 25 Aug 2021 15:41:47 +0000 (16:41 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 25 Aug 2021 15:42:23 +0000 (16:42 +0100)
src/libserver/async_session.c

index 1bd4c77e9b883eb0d9245c5f44ee6aeef75538bf..057604447fd9389aa04b55dd94f2e00a29a3ab76 100644 (file)
@@ -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;
 }